actually add time in
This commit is contained in:
parent
fcb852199b
commit
421bc7c768
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
zig-cache
|
zig-cache
|
||||||
|
zig-out
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,9 +1,6 @@
|
||||||
[submodule "deps/interfaces"]
|
[submodule "deps/interfaces"]
|
||||||
path = deps/interfaces
|
path = deps/interfaces
|
||||||
url = https://github.com/alexnask/interface.zig
|
url = https://github.com/alexnask/interface.zig
|
||||||
[submodule "deps/time"]
|
|
||||||
path = deps/time
|
|
||||||
url = https://github.com/purringChaos/time
|
|
||||||
[submodule "deps/hzzp"]
|
[submodule "deps/hzzp"]
|
||||||
path = deps/hzzp
|
path = deps/hzzp
|
||||||
url = https://github.com/truemedian/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