@@ -15,8 +15,9 @@ _inst: zeit.Instant,
1515
1616pub fn init (iso8601 : []const u8 ) ! DateTime {
1717 const date = try zeit .Time .fromISO8601 (iso8601 );
18+ const inst = date .instant ();
1819 return .{
19- ._inst = date . instant () ,
20+ ._inst = inst ,
2021 };
2122}
2223
@@ -126,6 +127,66 @@ pub const Builtins = struct {
126127 return Bool .init (dt ._inst .timestamp == rhs ._inst .timestamp );
127128 }
128129 };
130+
131+ pub const in = struct {
132+ pub const signature : Signature = .{
133+ .params = &.{.str },
134+ .ret = .Date ,
135+ };
136+ pub const docs_description =
137+ \\Change the Time Zone offset of a date with the offset
138+ \\of the location provided.
139+ ;
140+ pub const examples =
141+ \\$page.date.in("Europe/Berlin")
142+ ;
143+ pub fn call (
144+ dt : DateTime ,
145+ gpa : Allocator ,
146+ _ : * const context.Template ,
147+ args : []const Value ,
148+ ) ! Value {
149+ const arg_err : Value = .{
150+ .err = "expected 1 string argument" ,
151+ };
152+
153+ if (args .len != 1 ) return arg_err ;
154+
155+ const loc_str = switch (args [0 ]) {
156+ .string = > | d | d .value ,
157+ else = > return arg_err ,
158+ };
159+
160+ const location = std .meta .stringToEnum (
161+ zeit .Location ,
162+ loc_str ,
163+ ) orelse {
164+ return .errFmt (
165+ gpa ,
166+ "unknown time zone location: '{s}'" ,
167+ .{loc_str },
168+ );
169+ };
170+
171+ if (dt ._inst .timezone != & zeit .utc ) {
172+ return .{
173+ .err = "can only override dates that are expressed in UTC" ,
174+ };
175+ }
176+
177+ const tz = try gpa .create (zeit .TimeZone );
178+ tz .* = zeit .loadTimeZone (gpa , location , null ) catch | err | {
179+ return .errFmt (
180+ gpa ,
181+ "unexpected error while loading '{s}' time zone information: '{s}'" ,
182+ .{ loc_str , @errorName (err ) },
183+ );
184+ };
185+
186+ return .{ .date = .{ ._inst = dt ._inst .in (tz ) } };
187+ }
188+ };
189+
129190 pub const format = struct {
130191 pub const signature : Signature = .{
131192 .params = &.{.String },
0 commit comments