actually add time in
This commit is contained in:
parent
fcb852199b
commit
421bc7c768
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
zig-cache
|
||||
zig-cache
|
||||
zig-out
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,9 +1,6 @@
|
|||
[submodule "deps/interfaces"]
|
||||
path = deps/interfaces
|
||||
url = https://github.com/alexnask/interface.zig
|
||||
[submodule "deps/time"]
|
||||
path = deps/time
|
||||
url = https://github.com/purringChaos/time
|
||||
[submodule "deps/hzzp"]
|
||||
path = deps/hzzp
|
||||
url = https://github.com/truemedian/hzzp
|
||||
|
|
1
deps/time
vendored
1
deps/time
vendored
|
@ -1 +0,0 @@
|
|||
Subproject commit 6b5387fcd3007cf01c08b4f5136d24a6562be413
|
19
deps/time/LICENCE
vendored
Normal file
19
deps/time/LICENCE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2018 Geofrey Ernest <geofreyernest@live.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
3
deps/time/README.md
vendored
Normal file
3
deps/time/README.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# time
|
||||
|
||||
`time` for ziglang
|
74
deps/time/RELEASE_NOTES.md
vendored
Normal file
74
deps/time/RELEASE_NOTES.md
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Release notes for Time (v0.6.0)
|
||||
|
||||
This marks another notable release from `v0.3.1`. For anyone of you who isn't
|
||||
familiar with what this is all about, [time](https://github.com/gernest/time) is a time package for the zig
|
||||
programming language. It offers a clean API to manipulate and display time,
|
||||
this package also supports time zones.
|
||||
|
||||
## Notable changes
|
||||
|
||||
|
||||
### Print durations in a human format
|
||||
|
||||
`Duration.string` returns a human readable string for the duration.
|
||||
For instance if you want to print duration of one hour ,four minutes and 10 seconds.
|
||||
|
||||
```
|
||||
const hour = Duration.Hour.value;
|
||||
const minute = Duration.Minute.value;
|
||||
const second = Duration.Second.value;
|
||||
var d = Duration.init(hour + minute * 4 + second * 10);
|
||||
warn("duration is {} \n", d.string());
|
||||
```
|
||||
```
|
||||
duration is 1h4m10s
|
||||
```
|
||||
|
||||
|
||||
## date manipulations
|
||||
|
||||
### Time.addDate
|
||||
|
||||
You can add date value to an existing Time instance to get a new date.
|
||||
|
||||
For example
|
||||
|
||||
```
|
||||
var local = time.Location.getLocal();
|
||||
var ts = time.now(&local);
|
||||
var buf = try std.Buffer.init(std.debug.global_allocator, "");
|
||||
defer buf.deinit();
|
||||
try ts.string(&buf);
|
||||
warn("\ncurrent time is {}\n", buf.toSlice());
|
||||
|
||||
// let's add 1 year
|
||||
ts = ts.addDate(1, 0, 0);
|
||||
try ts.string(&buf);
|
||||
warn("this time next year is {}\n", buf.toSlice());
|
||||
```
|
||||
|
||||
```
|
||||
current time is 2018-12-08 10:32:30.000178063 +0300 EATm=+419006.837156719
|
||||
this time next year is 2019-12-08 10:32:30.000178063 +0300 EAT
|
||||
```
|
||||
|
||||
Please play with the api, you can add year,month,day. If you want to go back in
|
||||
time then use negative numbers. From the example above if you want to back one year then
|
||||
use `ts.addDate(-1, 0, 0)`
|
||||
|
||||
|
||||
This is just highlight, there are
|
||||
|
||||
- lots of bug fixes
|
||||
- cleanups to more idiomatic zig
|
||||
- lots of utility time goodies like `Time.beginningOfMonth`
|
||||
- improved documentation
|
||||
- lots of tests added
|
||||
- ... and so much more
|
||||
|
||||
I encourage you to take a look at it so you can experiment for yourself.
|
||||
|
||||
All kind of feedback is welcome.
|
||||
|
||||
Enjoy
|
||||
|
27
deps/time/ascii_calendar.md
vendored
Normal file
27
deps/time/ascii_calendar.md
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
This is part of [time](https://github.com/gernest/time) package. I think it is cool to showcase how far the package has matured.
|
||||
|
||||
`calendar.zig`
|
||||
|
||||
```
|
||||
const Time = @import("./src/time.zig").Time;
|
||||
|
||||
pub fn main() void {
|
||||
Time.calendar();
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
$ zig run calendar.zig
|
||||
|
||||
Sun |Mon |Tue |Wed |Thu |Fri |Sat |
|
||||
| | | | | | 1 |
|
||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
9 | 10 | 11 | 12 |*13 | 14 | 15 |
|
||||
16 | 17 | 18 | 19 | 20 | 21 | 22 |
|
||||
23 | 24 | 25 | 26 | 27 | 28 | 29 |
|
||||
30 | 31 | | | | | |
|
||||
```
|
||||
|
||||
Today's date is prefixed with `*` eg `*13`.
|
||||
|
||||
Enjoy.
|
10
deps/time/build.zig
vendored
Normal file
10
deps/time/build.zig
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
const mode = b.standardReleaseOptions();
|
||||
var main_tests = b.addTest("src/time_test.zig");
|
||||
main_tests.setBuildMode(mode);
|
||||
const test_step = b.step("test", "Run library tests");
|
||||
test_step.dependOn(&main_tests.step);
|
||||
b.default_step.dependOn(test_step);
|
||||
}
|
8
deps/time/calendar.zig
vendored
Normal file
8
deps/time/calendar.zig
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Calendar is a simple zig program that prints the calendar on the stdout. This
|
||||
// is to showcase maturity of the time library.
|
||||
|
||||
const Time = @import("./src/time.zig").Time;
|
||||
|
||||
pub fn main() void {
|
||||
Time.calendar();
|
||||
}
|
14
deps/time/docs/README.md
vendored
Normal file
14
deps/time/docs/README.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
# time
|
||||
|
||||
Time library for the zig programming language (ziglang).
|
||||
|
||||
|
||||
In my opinion, the go programming language offers a very elegant api for dealing with time.
|
||||
This library ports the [go standard library time package](). It is not 100% `1:1` mapping
|
||||
with the go counterpart but offers majority of what you might need for your time needs.
|
||||
|
||||
|
||||
# Locations and timezones
|
||||
|
||||
A time library isn't complete with timezone. This library supports timezone. I comes with
|
||||
a parser implementation for reading timezone info from all supported platforms.
|
1
deps/time/docs/_config.yml
vendored
Normal file
1
deps/time/docs/_config.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
theme: jekyll-theme-modernist
|
111
deps/time/example.zig
vendored
Normal file
111
deps/time/example.zig
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
const std = @import("std");
|
||||
const warn = std.debug.warn;
|
||||
const time = @import("./src/time.zig");
|
||||
const Duration = time.Duration;
|
||||
|
||||
test "now" {
|
||||
var local = time.Location.getLocal();
|
||||
var now = time.now(&local);
|
||||
|
||||
warn("\n today's date {}", .{now.date()});
|
||||
warn("\n today's time {}", .{now.clock()});
|
||||
warn("\n local timezone detail {}\n", .{now.zone()});
|
||||
|
||||
// $ zig test example.zig
|
||||
// Test 1/1 now...
|
||||
// today's date DateDetail{ .year = 2018, .month = Month.November, .day = 25, .yday = 328 }
|
||||
// today's time Clock{ .hour = 11, .min = 17, .sec = 16 }
|
||||
// local timezone detail ZoneDetail{ .name = EAT, .offset = 10800 }
|
||||
// OK
|
||||
// All tests passed.
|
||||
}
|
||||
|
||||
const formatTest = struct {
|
||||
name: []const u8,
|
||||
format: []const u8,
|
||||
fn init(name: []const u8, format: []const u8) formatTest {
|
||||
return formatTest{ .name = name, .format = format };
|
||||
}
|
||||
};
|
||||
|
||||
const format_tests = [_]formatTest{
|
||||
formatTest.init("ANSIC", time.ANSIC),
|
||||
formatTest.init("UnixDate", time.UnixDate),
|
||||
formatTest.init("RubyDate", time.RubyDate),
|
||||
formatTest.init("RFC822", time.RFC822),
|
||||
formatTest.init("RFC850", time.RFC850),
|
||||
formatTest.init("RFC1123", time.RFC1123),
|
||||
formatTest.init("RFC1123Z", time.RFC1123Z),
|
||||
formatTest.init("RFC3339", time.RFC3339),
|
||||
formatTest.init("RFC3339Nano", time.RFC3339Nano),
|
||||
formatTest.init("Kitchen", time.Kitchen),
|
||||
formatTest.init("am/pm", "3pm"),
|
||||
formatTest.init("AM/PM", "3PM"),
|
||||
formatTest.init("two-digit year", "06 01 02"),
|
||||
// Three-letter months and days must not be followed by lower-case letter.
|
||||
formatTest.init("Janet", "Hi Janet, the Month is January"),
|
||||
// Time stamps, Fractional seconds.
|
||||
formatTest.init("Stamp", time.Stamp),
|
||||
formatTest.init("StampMilli", time.StampMilli),
|
||||
formatTest.init("StampMicro", time.StampMicro),
|
||||
formatTest.init("StampNano", time.StampNano),
|
||||
};
|
||||
|
||||
test "time.format" {
|
||||
var local = time.Location.getLocal();
|
||||
var ts = time.now(&local);
|
||||
|
||||
var buf = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
warn("\n", .{});
|
||||
for (format_tests) |value| {
|
||||
try buf.resize(0);
|
||||
try ts.formatBuffer(&buf, value.format);
|
||||
warn("{}: {}\n", .{ value.name, buf.items });
|
||||
}
|
||||
|
||||
// Test 2/2 time.format...
|
||||
// ANSIC: Thu Nov 29 05:46:03 2018
|
||||
// UnixDate: Thu Nov 29 05:46:03 EAT 2018
|
||||
// RubyDate: Thu Nov 29 05:46:03 +0300 2018
|
||||
// RFC822: 29 Nov 18 05:46 EAT
|
||||
// RFC850: Thursday, 29-Nov-18 05:46:03 EAT
|
||||
// RFC1123: Thu, 29 Nov 2018 05:46:03 EAT
|
||||
// RFC1123Z: Thu, 29 Nov 2018 05:46:03 +0300
|
||||
// RFC3339: 2018-11-29T05:46:03+03:00
|
||||
// RFC3339Nano: 2018-11-29T05:46:03.000024416+03:00
|
||||
// Kitchen: 5:46AM
|
||||
// am/pm: 5am
|
||||
// AM/PM: 5AM
|
||||
// two-digit year: 18 11 29
|
||||
// Janet: Hi Janet, the Month is November
|
||||
// Stamp: Nov 29 05:46:03
|
||||
// StampMilli: Nov 29 05:46:03.000
|
||||
// StampMicro: Nov 29 05:46:03.000024
|
||||
// StampNano: Nov 29 05:46:03.000024416
|
||||
// OK
|
||||
// All tests passed.
|
||||
}
|
||||
|
||||
test "durations" {
|
||||
// print w0ne hour and 10 secods
|
||||
const hour = Duration.Hour.value;
|
||||
const minute = Duration.Minute.value;
|
||||
const second = Duration.Second.value;
|
||||
var d = Duration.init(hour + minute * 4 + second * 10);
|
||||
warn("duration is {} \n", .{d.string()});
|
||||
}
|
||||
|
||||
test "addDate" {
|
||||
var local = time.Location.getLocal();
|
||||
var ts = time.now(&local);
|
||||
var buf = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
try ts.string(&buf);
|
||||
warn("\ncurrent time is {}\n", .{buf.items});
|
||||
|
||||
// let's add 1 year
|
||||
ts = ts.addDate(1, 0, 0);
|
||||
try ts.string(&buf);
|
||||
warn("this time next year is {}\n", .{buf.items});
|
||||
}
|
112
deps/time/formating_time_with_zig.md
vendored
Normal file
112
deps/time/formating_time_with_zig.md
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
## formating timestamps with zig
|
||||
|
||||
Most of you are not aware of the [time package](https://github.com/gernest/time).
|
||||
A new release has just landed with support for formating time into various timestamps.
|
||||
|
||||
### Layouts
|
||||
Time is formatted into different layouts. A layout is a string which defines
|
||||
how time is formatted, for example `Mon Jan 2 15:04:05 MST 2006`.
|
||||
|
||||
You can read more about layouts
|
||||
here https://github.com/gernest/time/blob/a3d45b5f5b607b7bedd4d0d4ca12307f0d6ff52b/src/time.zig#L791-L850
|
||||
|
||||
I will focus on showcasing using the standard timestamp layouts that are provided by the library.
|
||||
|
||||
These are standard layouts provided by the library
|
||||
|
||||
```
|
||||
pub const ANSIC = "Mon Jan _2 15:04:05 2006";
|
||||
pub const UnixDate = "Mon Jan _2 15:04:05 MST 2006";
|
||||
pub const RubyDate = "Mon Jan 02 15:04:05 -0700 2006";
|
||||
pub const RFC822 = "02 Jan 06 15:04 MST";
|
||||
pub const RFC822Z = "02 Jan 06 15:04 -0700"; // RFC822 with numeric zone
|
||||
pub const RFC850 = "Monday, 02-Jan-06 15:04:05 MST";
|
||||
pub const RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST";
|
||||
pub const RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700"; // RFC1123 with numeric zone
|
||||
pub const RFC3339 = "2006-01-02T15:04:05Z07:00";
|
||||
pub const RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00";
|
||||
pub const Kitchen = "3:04PM";
|
||||
// Handy time stamps.
|
||||
pub const Stamp = "Jan _2 15:04:05";
|
||||
pub const StampMilli = "Jan _2 15:04:05.000";
|
||||
pub const StampMicro = "Jan _2 15:04:05.000000";
|
||||
pub const StampNano = "Jan _2 15:04:05.000000000";
|
||||
```
|
||||
|
||||
### show me some code
|
||||
|
||||
```
|
||||
const std = @import("std");
|
||||
const warn = std.debug.warn;
|
||||
const time = @import("./src/time.zig");
|
||||
|
||||
|
||||
const formatTest = struct {
|
||||
name: []const u8,
|
||||
format: []const u8,
|
||||
fn init(name: []const u8, format: []const u8) formatTest {
|
||||
return formatTest{ .name = name, .format = format };
|
||||
}
|
||||
};
|
||||
|
||||
const format_tests = []formatTest{
|
||||
formatTest.init("ANSIC", time.ANSIC),
|
||||
formatTest.init("UnixDate", time.UnixDate),
|
||||
formatTest.init("RubyDate", time.RubyDate),
|
||||
formatTest.init("RFC822", time.RFC822),
|
||||
formatTest.init("RFC850", time.RFC850),
|
||||
formatTest.init("RFC1123", time.RFC1123),
|
||||
formatTest.init("RFC1123Z", time.RFC1123Z),
|
||||
formatTest.init("RFC3339", time.RFC3339),
|
||||
formatTest.init("RFC3339Nano", time.RFC3339Nano),
|
||||
formatTest.init("Kitchen", time.Kitchen),
|
||||
formatTest.init("am/pm", "3pm"),
|
||||
formatTest.init("AM/PM", "3PM"),
|
||||
formatTest.init("two-digit year", "06 01 02"),
|
||||
// Three-letter months and days must not be followed by lower-case letter.
|
||||
formatTest.init("Janet", "Hi Janet, the Month is January"),
|
||||
// Time stamps, Fractional seconds.
|
||||
formatTest.init("Stamp", time.Stamp),
|
||||
formatTest.init("StampMilli", time.StampMilli),
|
||||
formatTest.init("StampMicro", time.StampMicro),
|
||||
formatTest.init("StampNano", time.StampNano),
|
||||
};
|
||||
|
||||
test "time.format" {
|
||||
var ts = time.now();
|
||||
var buf = try std.Buffer.init(std.debug.global_allocator, "");
|
||||
defer buf.deinit();
|
||||
warn("\n");
|
||||
for (format_tests) |value| {
|
||||
try ts.format(&buf, value.format);
|
||||
const got = buf.toSlice();
|
||||
warn("{}: {}\n", value.name, got);
|
||||
}
|
||||
|
||||
// Test 2/2 time.format...
|
||||
// ANSIC: Thu Nov 29 05:46:03 2018
|
||||
// UnixDate: Thu Nov 29 05:46:03 EAT 2018
|
||||
// RubyDate: Thu Nov 29 05:46:03 +0300 2018
|
||||
// RFC822: 29 Nov 18 05:46 EAT
|
||||
// RFC850: Thursday, 29-Nov-18 05:46:03 EAT
|
||||
// RFC1123: Thu, 29 Nov 2018 05:46:03 EAT
|
||||
// RFC1123Z: Thu, 29 Nov 2018 05:46:03 +0300
|
||||
// RFC3339: 2018-11-29T05:46:03+03:00
|
||||
// RFC3339Nano: 2018-11-29T05:46:03.000024416+03:00
|
||||
// Kitchen: 5:46AM
|
||||
// am/pm: 5am
|
||||
// AM/PM: 5AM
|
||||
// two-digit year: 18 11 29
|
||||
// Janet: Hi Janet, the Month is November
|
||||
// Stamp: Nov 29 05:46:03
|
||||
// StampMilli: Nov 29 05:46:03.000
|
||||
// StampMicro: Nov 29 05:46:03.000024
|
||||
// StampNano: Nov 29 05:46:03.000024416
|
||||
// OK
|
||||
// All tests passed.
|
||||
}
|
||||
```
|
||||
|
||||
All kind of feedback is welcome.
|
||||
|
||||
Enjoy.
|
2889
deps/time/src/time.zig
vendored
Normal file
2889
deps/time/src/time.zig
vendored
Normal file
File diff suppressed because it is too large
Load diff
357
deps/time/src/time_test.zig
vendored
Normal file
357
deps/time/src/time_test.zig
vendored
Normal file
|
@ -0,0 +1,357 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// Copyright 2018 Geofrey Ernest MIT LICENSE
|
||||
|
||||
const std = @import("std");
|
||||
const time = @import("time.zig");
|
||||
|
||||
const April = time.Month.April;
|
||||
const December = time.Month.December;
|
||||
const January = time.Month.January;
|
||||
const Location = time.Location;
|
||||
const Monday = time.Weekday.Monday;
|
||||
const Saturday = time.Weekday.Saturday;
|
||||
const September = time.Month.September;
|
||||
const Sunday = time.Weekday.Sunday;
|
||||
const Thursday = time.Weekday.Thursday;
|
||||
const Wednesday = time.Weekday.Wednesday;
|
||||
const math = std.math;
|
||||
const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
|
||||
const failed_test = error.Failed;
|
||||
|
||||
const parsedTime = struct {
|
||||
year: isize,
|
||||
month: time.Month,
|
||||
day: isize,
|
||||
hour: isize,
|
||||
minute: isize,
|
||||
second: isize,
|
||||
nanosecond: isize,
|
||||
weekday: time.Weekday,
|
||||
zone_offset: isize,
|
||||
zone: []const u8,
|
||||
|
||||
fn init(year: isize, month: time.Month, day: isize, hour: isize, minute: isize, second: isize, nanosecond: isize, weekday: time.Weekday, zone_offset: isize, zone: []const u8) parsedTime {
|
||||
return parsedTime{
|
||||
.year = year,
|
||||
.month = month,
|
||||
.day = day,
|
||||
.hour = hour,
|
||||
.minute = minute,
|
||||
.second = second,
|
||||
.nanosecond = nanosecond,
|
||||
.weekday = weekday,
|
||||
.zone_offset = zone_offset,
|
||||
.zone = zone,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const TimeTest = struct {
|
||||
seconds: i64,
|
||||
golden: parsedTime,
|
||||
};
|
||||
|
||||
const utc_tests = [_]TimeTest{
|
||||
TimeTest{ .seconds = 0, .golden = parsedTime.init(1970, January, 1, 0, 0, 0, 0, Thursday, 0, "UTC") },
|
||||
TimeTest{ .seconds = 1221681866, .golden = parsedTime.init(2008, September, 17, 20, 4, 26, 0, Wednesday, 0, "UTC") },
|
||||
TimeTest{ .seconds = -1221681866, .golden = parsedTime.init(1931, April, 16, 3, 55, 34, 0, Thursday, 0, "UTC") },
|
||||
TimeTest{ .seconds = -11644473600, .golden = parsedTime.init(1601, January, 1, 0, 0, 0, 0, Monday, 0, "UTC") },
|
||||
TimeTest{ .seconds = 599529660, .golden = parsedTime.init(1988, December, 31, 0, 1, 0, 0, Saturday, 0, "UTC") },
|
||||
TimeTest{ .seconds = 978220860, .golden = parsedTime.init(2000, December, 31, 0, 1, 0, 0, Sunday, 0, "UTC") },
|
||||
};
|
||||
|
||||
const nano_tests = [_]TimeTest{
|
||||
TimeTest{ .seconds = 0, .golden = parsedTime.init(1970, January, 1, 0, 0, 0, 1e8, Thursday, 0, "UTC") },
|
||||
TimeTest{ .seconds = 1221681866, .golden = parsedTime.init(2008, September, 17, 20, 4, 26, 2e8, Wednesday, 0, "UTC") },
|
||||
};
|
||||
|
||||
const local_tests = [_]TimeTest{
|
||||
TimeTest{ .seconds = 0, .golden = parsedTime.init(1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST") },
|
||||
TimeTest{ .seconds = 1221681866, .golden = parsedTime.init(2008, September, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT") },
|
||||
};
|
||||
|
||||
const nano_local_tests = [_]TimeTest{
|
||||
TimeTest{ .seconds = 0, .golden = parsedTime.init(1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST") },
|
||||
TimeTest{ .seconds = 1221681866, .golden = parsedTime.init(2008, September, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT") },
|
||||
};
|
||||
|
||||
fn same(t: time.Time, u: *parsedTime) bool {
|
||||
const date = t.date();
|
||||
const clock = t.clock();
|
||||
const zone = t.zone();
|
||||
const check = date.year != u.year or @enumToInt(date.month) != @enumToInt(u.month) or
|
||||
date.day != u.day or clock.hour != u.hour or clock.min != u.minute or clock.sec != u.second or
|
||||
!mem.eql(u8, zone.name, u.zone) or zone.offset != u.zone_offset;
|
||||
if (check) {
|
||||
return false;
|
||||
}
|
||||
return t.year() == u.year and
|
||||
@enumToInt(t.month()) == @enumToInt(u.month) and
|
||||
t.day() == u.day and
|
||||
t.hour() == u.hour and
|
||||
t.minute() == u.minute and
|
||||
t.second() == u.second and
|
||||
t.nanosecond() == u.nanosecond and
|
||||
@enumToInt(t.weekday()) == @enumToInt(u.weekday);
|
||||
}
|
||||
|
||||
test "TestSecondsToUTC" {
|
||||
// try skip();
|
||||
for (utc_tests) |ts| {
|
||||
var tm = time.unix(ts.seconds, 0, &Location.utc_local);
|
||||
const ns = tm.unix();
|
||||
testing.expectEqual(ns, ts.seconds);
|
||||
var golden = ts.golden;
|
||||
testing.expect(same(tm, &golden));
|
||||
}
|
||||
}
|
||||
|
||||
test "TestNanosecondsToUTC" {
|
||||
// try skip();
|
||||
for (nano_tests) |tv| {
|
||||
var golden = tv.golden;
|
||||
const nsec = tv.seconds * @as(i64, 1e9) + @intCast(i64, golden.nanosecond);
|
||||
var tm = time.unix(0, nsec, &Location.utc_local);
|
||||
const new_nsec = tm.unix() * @as(i64, 1e9) + @intCast(i64, tm.nanosecond());
|
||||
testing.expectEqual(new_nsec, nsec);
|
||||
testing.expect(same(tm, &golden));
|
||||
}
|
||||
}
|
||||
|
||||
test "TestSecondsToLocalTime" {
|
||||
// try skip();
|
||||
var loc = try Location.load("US/Pacific");
|
||||
defer loc.deinit();
|
||||
for (local_tests) |tv| {
|
||||
var golden = tv.golden;
|
||||
const sec = tv.seconds;
|
||||
var tm = time.unix(sec, 0, &loc);
|
||||
const new_sec = tm.unix();
|
||||
testing.expectEqual(new_sec, sec);
|
||||
testing.expect(same(tm, &golden));
|
||||
}
|
||||
}
|
||||
|
||||
test "TestNanosecondsToUTC" {
|
||||
// try skip();
|
||||
var loc = try Location.load("US/Pacific");
|
||||
defer loc.deinit();
|
||||
for (nano_local_tests) |tv| {
|
||||
var golden = tv.golden;
|
||||
const nsec = tv.seconds * @as(i64, 1e9) + @intCast(i64, golden.nanosecond);
|
||||
var tm = time.unix(0, nsec, &loc);
|
||||
const new_nsec = tm.unix() * @as(i64, 1e9) + @intCast(i64, tm.nanosecond());
|
||||
testing.expectEqual(new_nsec, nsec);
|
||||
testing.expect(same(tm, &golden));
|
||||
}
|
||||
}
|
||||
|
||||
const formatTest = struct {
|
||||
name: []const u8,
|
||||
format: []const u8,
|
||||
result: []const u8,
|
||||
|
||||
fn init(name: []const u8, format: []const u8, result: []const u8) formatTest {
|
||||
return formatTest{ .name = name, .format = format, .result = result };
|
||||
}
|
||||
};
|
||||
|
||||
const format_tests = [_]formatTest{
|
||||
formatTest.init("ANSIC", time.ANSIC, "Wed Feb 4 21:00:57 2009"),
|
||||
formatTest.init("UnixDate", time.UnixDate, "Wed Feb 4 21:00:57 PST 2009"),
|
||||
formatTest.init("RubyDate", time.RubyDate, "Wed Feb 04 21:00:57 -0800 2009"),
|
||||
formatTest.init("RFC822", time.RFC822, "04 Feb 09 21:00 PST"),
|
||||
formatTest.init("RFC850", time.RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"),
|
||||
formatTest.init("RFC1123", time.RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"),
|
||||
formatTest.init("RFC1123Z", time.RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"),
|
||||
formatTest.init("RFC3339", time.RFC3339, "2009-02-04T21:00:57-08:00"),
|
||||
formatTest.init("RFC3339Nano", time.RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"),
|
||||
formatTest.init("Kitchen", time.Kitchen, "9:00PM"),
|
||||
formatTest.init("am/pm", "3pm", "9pm"),
|
||||
formatTest.init("AM/PM", "3PM", "9PM"),
|
||||
formatTest.init("two-digit year", "06 01 02", "09 02 04"),
|
||||
// Three-letter months and days must not be followed by lower-case letter.
|
||||
formatTest.init("Janet", "Hi Janet, the Month is January", "Hi Janet, the Month is February"),
|
||||
// Time stamps, Fractional seconds.
|
||||
formatTest.init("Stamp", time.Stamp, "Feb 4 21:00:57"),
|
||||
formatTest.init("StampMilli", time.StampMilli, "Feb 4 21:00:57.012"),
|
||||
formatTest.init("StampMicro", time.StampMicro, "Feb 4 21:00:57.012345"),
|
||||
formatTest.init("StampNano", time.StampNano, "Feb 4 21:00:57.012345600"),
|
||||
};
|
||||
|
||||
test "TestFormat" {
|
||||
// try skip();
|
||||
var tz = try Location.load("US/Pacific");
|
||||
defer tz.deinit();
|
||||
var ts = time.unix(0, 1233810057012345600, &tz);
|
||||
var buf = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
for (format_tests) |value| {
|
||||
try buf.resize(0);
|
||||
try ts.formatBuffer(&buf, value.format);
|
||||
testing.expect(std.mem.eql(u8, buf.items, value.result));
|
||||
}
|
||||
}
|
||||
|
||||
test "calendar" {
|
||||
// try skip();
|
||||
time.Time.calendar();
|
||||
}
|
||||
|
||||
fn skip() !void {
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
|
||||
test "TestFormatSingleDigits" {
|
||||
// try skip();
|
||||
var buf = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
var tt = time.date(2001, 2, 3, 4, 5, 6, 700000000, &Location.utc_local);
|
||||
const ts = formatTest.init("single digit format", "3:4:5", "4:5:6");
|
||||
|
||||
try tt.formatBuffer(&buf, ts.format);
|
||||
testing.expect(std.mem.eql(u8, buf.items, ts.result));
|
||||
|
||||
try buf.resize(0);
|
||||
|
||||
try buf.outStream().print("{}", .{tt});
|
||||
const want = "2001-02-03 04:05:06.7 +0000 UTC";
|
||||
testing.expect(std.mem.eql(u8, buf.items, want));
|
||||
}
|
||||
|
||||
test "TestFormatShortYear" {
|
||||
// try skip();
|
||||
var buf = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
var want = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer want.deinit();
|
||||
|
||||
const years = [_]isize{
|
||||
-100001, -100000, -99999,
|
||||
-10001, -10000, -9999,
|
||||
-1001, -1000, -999,
|
||||
-101, -100, -99,
|
||||
-11, -10, -9,
|
||||
-1, 0, 1,
|
||||
9, 10, 11,
|
||||
99, 100, 101,
|
||||
999, 1000, 1001,
|
||||
9999, 10000, 10001,
|
||||
99999, 100000, 100001,
|
||||
};
|
||||
for (years) |y| {
|
||||
const m = @enumToInt(January);
|
||||
const x = @intCast(isize, m);
|
||||
var tt = time.date(y, x, 1, 0, 0, 0, 0, &Location.utc_local);
|
||||
try buf.resize(0);
|
||||
try tt.formatBuffer(&buf, "2006.01.02");
|
||||
try want.resize(0);
|
||||
const day: usize = 1;
|
||||
const month: usize = 1;
|
||||
if (y < 0) {
|
||||
try buf.outStream().print("-{d:4}.{d:2}.{d:2}", .{ math.absCast(y), month, day });
|
||||
} else {
|
||||
try buf.outStream().print("{d:4}.{d:2}.{d:2}", .{ math.absCast(y), month, day });
|
||||
}
|
||||
if (!std.mem.eql(u8, buf.items, want.items)) {
|
||||
std.debug.warn("case: {} expected {} got {}\n", .{ y, want.items, buf.items });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "TestNextStdChunk" {
|
||||
const next_std_chunk_tests = [_][]const u8{
|
||||
"(2006)-(01)-(02)T(15):(04):(05)(Z07:00)",
|
||||
"(2006)-(01)-(02) (002) (15):(04):(05)",
|
||||
"(2006)-(01) (002) (15):(04):(05)",
|
||||
"(2006)-(002) (15):(04):(05)",
|
||||
"(2006)(002)(01) (15):(04):(05)",
|
||||
"(2006)(002)(04) (15):(04):(05)",
|
||||
};
|
||||
var buf = std.ArrayList([]const u8).init(std.testing.allocator);
|
||||
defer buf.deinit();
|
||||
for (next_std_chunk_tests) |marked, i| {
|
||||
try markChunk(&buf, marked);
|
||||
// FIXME: fix check, buf.items doesn't work
|
||||
// testing.expect(std.mem.eql([]const u8, buf.items, bufM.items));
|
||||
}
|
||||
}
|
||||
|
||||
var tmp: [39]u8 = undefined;
|
||||
|
||||
fn removeParen(format: []const u8) []const u8 {
|
||||
var s = tmp[0..format.len];
|
||||
var i: usize = 0;
|
||||
var n = i;
|
||||
while (i < format.len) : (i += 1) {
|
||||
if (format[i] == '(' or format[i] == ')') {
|
||||
continue;
|
||||
}
|
||||
s[n] = format[i];
|
||||
n += 1;
|
||||
}
|
||||
return s[0..n];
|
||||
}
|
||||
|
||||
fn markChunk(buf: *std.ArrayList([]const u8), format: []const u8) !void {
|
||||
try buf.resize(0);
|
||||
var s = removeParen(format);
|
||||
|
||||
while (s.len > 0) {
|
||||
var ch = time.nextStdChunk(s);
|
||||
try buf.append(ch.prefix);
|
||||
if (ch.chunk != .none) {
|
||||
try buf.append("(");
|
||||
try buf.append(chunName(ch.chunk));
|
||||
try buf.append(")");
|
||||
}
|
||||
s = ch.suffix;
|
||||
}
|
||||
}
|
||||
|
||||
fn chunName(ch: time.chunk) []const u8 {
|
||||
return switch (ch) {
|
||||
.none => "",
|
||||
.stdLongMonth => "January",
|
||||
.stdMonth => "Jan",
|
||||
.stdNumMonth => "1",
|
||||
.stdZeroMonth => "01",
|
||||
.stdLongWeekDay => "Monday",
|
||||
.stdWeekDay => "Mon",
|
||||
.stdDay => "2",
|
||||
.stdUnderDay => "_2",
|
||||
.stdZeroDay => "02",
|
||||
.stdUnderYearDay => "__2",
|
||||
.stdZeroYearDay => "002",
|
||||
.stdHour => "15",
|
||||
.stdHour12 => "3",
|
||||
.stdZeroHour12 => "03",
|
||||
.stdMinute => "4",
|
||||
.stdZeroMinute => "04",
|
||||
.stdSecond => "5",
|
||||
.stdZeroSecond => "05",
|
||||
.stdLongYear => "2006",
|
||||
.stdYear => "06",
|
||||
.stdPM => "PM",
|
||||
.stdpm => "pm",
|
||||
.stdTZ => "MST",
|
||||
.stdISO8601TZ => "Z0700",
|
||||
.stdISO8601SecondsTZ => "Z070000",
|
||||
.stdISO8601ShortTZ => "Z07",
|
||||
.stdISO8601ColonTZ => "Z07:00",
|
||||
.stdISO8601ColonSecondsTZ => "Z07:00:00",
|
||||
.stdNumTZ => "-0700",
|
||||
.stdNumSecondsTz => "-070000",
|
||||
.stdNumShortTZ => "-07",
|
||||
.stdNumColonTZ => "-07:00",
|
||||
.stdNumColonSecondsTZ => "-07:00:00",
|
||||
else => "unknown",
|
||||
};
|
||||
}
|
3
deps/time/z.mod
vendored
Normal file
3
deps/time/z.mod
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
module github.com/gernest/time
|
||||
|
||||
exports time
|
Loading…
Reference in a new issue