1
- //! Epoch reference times in terms of their difference from
2
- //! UTC 1970-01-01 in seconds.
1
+ //! Epoch reference times in terms of their difference from UTC 1970-01-01 in seconds.
2
+
3
3
const std = @import ("../std.zig" );
4
+ const time = std .time ;
4
5
const testing = std .testing ;
5
6
const math = std .math ;
6
7
7
- /// Jan 01, 1970 AD
8
+ /// 1970-01-01.
8
9
pub const posix = 0 ;
9
- /// Jan 01, 1980 AD
10
+ /// 1980-01-01.
10
11
pub const dos = 315532800 ;
11
- /// Jan 01, 2001 AD
12
+ /// 2001-01-01.
12
13
pub const ios = 978307200 ;
13
- /// Nov 17, 1858 AD
14
+ /// 1858-11-17.
14
15
pub const openvms = -3506716800 ;
15
- /// Jan 01, 1900 AD
16
+ /// 1900-01-01.
16
17
pub const zos = -2208988800 ;
17
- /// Jan 01, 1601 AD
18
+ /// 1601-01-01.
18
19
pub const windows = -11644473600 ;
19
- /// Jan 01, 1978 AD
20
+ /// 1978-01-01.
20
21
pub const amiga = 252460800 ;
21
- /// Dec 31, 1967 AD
22
+ /// 1967-12-31.
22
23
pub const pickos = -63244800 ;
23
- /// Jan 06, 1980 AD
24
+ /// 1980-01-06.
24
25
pub const gps = 315964800 ;
25
- /// Jan 01, 0001 AD
26
+ /// 0001-01-01.
26
27
pub const clr = -62135769600 ;
27
28
28
29
pub const unix = posix ;
@@ -39,10 +40,13 @@ pub const brew = gps;
39
40
pub const atsc = gps ;
40
41
pub const go = clr ;
41
42
42
- /// The type that holds the current year, i.e. 2016
43
+ /// Example: 2016.
43
44
pub const Year = u16 ;
44
45
46
+ /// Deprecated: use functions provided by this structure.
45
47
pub const epoch_year = 1970 ;
48
+
49
+ /// Deprecated: use `std.time.s_per_day`.
46
50
pub const secs_per_day : u17 = 24 * 60 * 60 ;
47
51
48
52
pub fn isLeapYear (year : Year ) bool {
@@ -78,21 +82,20 @@ pub const Month = enum(u4) {
78
82
nov ,
79
83
dec ,
80
84
81
- /// return the numeric calendar value for the given month
82
- /// i.e. jan=1, feb=2, etc
83
- pub fn numeric (self : Month ) u4 {
84
- return @intFromEnum (self );
85
+ /// Returns the numeric calendar value for the given month, i.e. jan=1, feb=2, etc.
86
+ pub fn numeric (month : Month ) u4 {
87
+ return @intFromEnum (month );
85
88
}
86
89
};
87
90
88
- /// Get the number of days in the given month and year
91
+ /// Returns the number of days in the given year and month.
89
92
pub fn getDaysInMonth (year : Year , month : Month ) u5 {
90
93
return switch (month ) {
91
94
.jan = > 31 ,
92
- .feb = > @as ( u5 , switch (isLeapYear (year )) {
95
+ .feb = > switch (isLeapYear (year )) {
93
96
true = > 29 ,
94
97
false = > 28 ,
95
- }) ,
98
+ },
96
99
.mar = > 31 ,
97
100
.apr = > 30 ,
98
101
.may = > 31 ,
@@ -106,118 +109,124 @@ pub fn getDaysInMonth(year: Year, month: Month) u5 {
106
109
};
107
110
}
108
111
109
- pub const YearAndDay = struct {
112
+ /// The year of the time and the number of days into the year.
113
+ pub const YearAndDays = struct {
110
114
year : Year ,
111
- /// The number of days into the year (0 to 365)
112
- day : u9 ,
115
+ /// The number of days into the year (0 to 365).
116
+ days : u9 ,
113
117
114
- pub fn calculateMonthDay ( self : YearAndDay ) MonthAndDay {
118
+ pub fn calculateMonthAndDay ( year_and_days : YearAndDays ) MonthAndDay {
115
119
var month : Month = .jan ;
116
- var days_left = self . day ;
120
+ var days_left = year_and_days . days ;
117
121
while (true ) {
118
- const days_in_month = getDaysInMonth (self .year , month );
122
+ const days_in_month = getDaysInMonth (year_and_days .year , month );
119
123
if (days_left < days_in_month )
120
124
break ;
121
125
days_left -= days_in_month ;
122
- month = @as ( Month , @ enumFromInt (@intFromEnum (month ) + 1 ) );
126
+ month = @enumFromInt (@intFromEnum (month ) + 1 );
123
127
}
124
- return .{ .month = month , .day_index = @as ( u5 , @ intCast (days_left ) ) };
128
+ return .{ .month = month , .day_index = @intCast (days_left ) };
125
129
}
126
130
};
127
131
132
+ /// The month and day of the time.
128
133
pub const MonthAndDay = struct {
129
134
month : Month ,
130
- day_index : u5 , // days into the month (0 to 30)
135
+ /// The day of the month (0 to 30).
136
+ day_index : u5 ,
131
137
};
132
138
133
- /// days since epoch Jan 1, 1970
134
- pub const EpochDay = struct {
135
- day : u47 , // u47 = u64 - u17 (because day = sec(u64) / secs_per_day(u17)
136
- pub fn calculateYearDay (self : EpochDay ) YearAndDay {
137
- var year_day = self .day ;
138
- var year : Year = epoch_year ;
139
+ /// Days since the epoch.
140
+ pub const Days = struct {
141
+ days : u47 , // = u64 - u17 (because day = sec(u64) / time.s_per_day(u17)
142
+
143
+ pub fn calculateYearAndDays (days : Days ) YearAndDays {
144
+ var year_days = days .days ;
145
+ var year : Year = 1970 ;
139
146
while (true ) {
140
147
const year_size = getDaysInYear (year );
141
- if (year_day < year_size )
148
+ if (year_days < year_size )
142
149
break ;
143
- year_day -= year_size ;
150
+ year_days -= year_size ;
144
151
year += 1 ;
145
152
}
146
- return .{ .year = year , .day = @as ( u9 , @ intCast (year_day ) ) };
153
+ return .{ .year = year , .days = @intCast (year_days ) };
147
154
}
148
155
};
149
156
150
- /// seconds since start of day
157
+ /// Seconds into the day.
151
158
pub const DaySeconds = struct {
152
- secs : u17 , // max is 24*60*60 = 86400
159
+ secs : u17 , // Maximum is `time.s_per_day`.
153
160
154
- /// the number of hours past the start of the day (0 to 23)
155
- pub fn getHoursIntoDay (self : DaySeconds ) u5 {
156
- return @as ( u5 , @ intCast (@divTrunc (self .secs , 3600 ) ));
161
+ /// Returns the number of hours past the start of the day (0 to 23).
162
+ pub fn getHoursIntoDay (day_seconds : DaySeconds ) u5 {
163
+ return @intCast (@divTrunc (day_seconds .secs , 3600 ));
157
164
}
158
- /// the number of minutes past the hour (0 to 59)
159
- pub fn getMinutesIntoHour (self : DaySeconds ) u6 {
160
- return @as (u6 , @intCast (@divTrunc (@mod (self .secs , 3600 ), 60 )));
165
+
166
+ /// Returns the number of minutes past the hour (0 to 59).
167
+ pub fn getMinutesIntoHour (day_seconds : DaySeconds ) u6 {
168
+ return @intCast (@divTrunc (@mod (day_seconds .secs , 3600 ), 60 ));
161
169
}
162
- /// the number of seconds past the start of the minute (0 to 59)
163
- pub fn getSecondsIntoMinute (self : DaySeconds ) u6 {
164
- return math .comptimeMod (self .secs , 60 );
170
+
171
+ /// Returns the number of seconds past the start of the minute (0 to 59).
172
+ pub fn getSecondsIntoMinute (day_seconds : DaySeconds ) u6 {
173
+ return math .comptimeMod (day_seconds .secs , 60 );
165
174
}
166
175
};
167
176
168
- /// seconds since epoch Jan 1, 1970 at 12:00 AM
169
- pub const EpochSeconds = struct {
177
+ /// Seconds since the epoch.
178
+ pub const Seconds = struct {
170
179
secs : u64 ,
171
180
172
- /// Returns the number of days since the epoch as an EpochDay .
173
- /// Use EpochDay to get information about the day of this time.
174
- pub fn getEpochDay ( self : EpochSeconds ) EpochDay {
175
- return EpochDay { .day = @as ( u47 , @ intCast (@divTrunc (self .secs , secs_per_day ) )) };
181
+ /// Returns the number of days since the epoch as an Days .
182
+ /// Use Days to get information about the day of this time.
183
+ pub fn getDays ( seconds : Seconds ) Days {
184
+ return Days { .days = @intCast (@divTrunc (seconds .secs , time . s_per_day )) };
176
185
}
177
186
178
187
/// Returns the number of seconds into the day as DaySeconds.
179
188
/// Use DaySeconds to get information about the time.
180
- pub fn getDaySeconds ( self : EpochSeconds ) DaySeconds {
181
- return DaySeconds { .secs = math .comptimeMod (self .secs , secs_per_day ) };
189
+ pub fn getSecondsIntoDay ( seconds : Seconds ) DaySeconds {
190
+ return DaySeconds { .secs = math .comptimeMod (seconds .secs , time . s_per_day ) };
182
191
}
183
192
};
184
193
185
- fn testEpoch (secs : u64 , expected_year_day : YearAndDay , expected_month_day : MonthAndDay , expected_day_seconds : struct {
186
- /// 0 to 23
194
+ fn testDecode (secs : u64 , expected_year_day : YearAndDays , expected_month_day : MonthAndDay , expected_day_seconds : struct {
195
+ /// 0 to 23.
187
196
hours_into_day : u5 ,
188
- /// 0 to 59
197
+ /// 0 to 59.
189
198
minutes_into_hour : u6 ,
190
- /// 0 to 59
199
+ /// 0 to 59.
191
200
seconds_into_minute : u6 ,
192
201
}) ! void {
193
- const epoch_seconds = EpochSeconds { .secs = secs };
194
- const epoch_day = epoch_seconds . getEpochDay ();
195
- const day_seconds = epoch_seconds . getDaySeconds ();
196
- const year_day = epoch_day . calculateYearDay ();
197
- try testing .expectEqual (expected_year_day , year_day );
198
- try testing .expectEqual (expected_month_day , year_day . calculateMonthDay ());
202
+ const seconds = Seconds { .secs = secs };
203
+ const days = seconds . getDays ();
204
+ const day_seconds = seconds . getSecondsIntoDay ();
205
+ const year_and_days = days . calculateYearAndDays ();
206
+ try testing .expectEqual (expected_year_day , year_and_days );
207
+ try testing .expectEqual (expected_month_day , year_and_days . calculateMonthAndDay ());
199
208
try testing .expectEqual (expected_day_seconds .hours_into_day , day_seconds .getHoursIntoDay ());
200
209
try testing .expectEqual (expected_day_seconds .minutes_into_hour , day_seconds .getMinutesIntoHour ());
201
210
try testing .expectEqual (expected_day_seconds .seconds_into_minute , day_seconds .getSecondsIntoMinute ());
202
211
}
203
212
204
- test "epoch decoding" {
205
- try testEpoch (0 , .{ .year = 1970 , .day = 0 }, .{
213
+ test "decoding" {
214
+ try testDecode (0 , .{ .year = 1970 , .days = 0 }, .{
206
215
.month = .jan ,
207
216
.day_index = 0 ,
208
217
}, .{ .hours_into_day = 0 , .minutes_into_hour = 0 , .seconds_into_minute = 0 });
209
218
210
- try testEpoch (31535999 , .{ .year = 1970 , .day = 364 }, .{
219
+ try testDecode (31535999 , .{ .year = 1970 , .days = 364 }, .{
211
220
.month = .dec ,
212
221
.day_index = 30 ,
213
222
}, .{ .hours_into_day = 23 , .minutes_into_hour = 59 , .seconds_into_minute = 59 });
214
223
215
- try testEpoch (1622924906 , .{ .year = 2021 , .day = 31 + 28 + 31 + 30 + 31 + 4 }, .{
224
+ try testDecode (1622924906 , .{ .year = 2021 , .days = 31 + 28 + 31 + 30 + 31 + 4 }, .{
216
225
.month = .jun ,
217
226
.day_index = 4 ,
218
227
}, .{ .hours_into_day = 20 , .minutes_into_hour = 28 , .seconds_into_minute = 26 });
219
228
220
- try testEpoch (1625159473 , .{ .year = 2021 , .day = 31 + 28 + 31 + 30 + 31 + 30 }, .{
229
+ try testDecode (1625159473 , .{ .year = 2021 , .days = 31 + 28 + 31 + 30 + 31 + 30 }, .{
221
230
.month = .jul ,
222
231
.day_index = 0 ,
223
232
}, .{ .hours_into_day = 17 , .minutes_into_hour = 11 , .seconds_into_minute = 13 });
0 commit comments