Skip to content

Commit

Permalink
Revise ISO parser, add common formats (#20)
Browse files Browse the repository at this point in the history
* prep common formats

* update readme

* draft new iso parser

* add modifier for a, A, b, B directives, add j directive

* update changelog
  • Loading branch information
FObersteiner authored Oct 3, 2024
1 parent 02feed9 commit 99e1d05
Show file tree
Hide file tree
Showing 7 changed files with 418 additions and 158 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ Types of changes

## Unreleased

## 2024-10-03, v0.3.2

### Added

- ISO8601 parser:
- '-' as a year-month or month-day separator now optional
- ':' as a hour-minute or minute-second separator now optional
- capability to parse day-of-year (ordinal; 'yyyy-ooo' format)
- Datetime from string / Parser:
- 'j' directive to parse day-of-year
- Datetime to string / Formatter:
- 's' directive to get Unix time in seconds
- ':a', ':A', ':b', ':B' (modifier option) to get English day / month names, independent of locale

### Changed

- internal: ISO8601 parser revised

## 2024-09-30, v0.3.1

### Added
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
**Datetime with Timezones in Zig.** Opinionated, and mostly for learning purposes.

- [API overview](https://github.com/FObersteiner/zdt/wiki/API-overview)
- [Demo](https://github.com/FObersteiner/zdt/blob/master/examples/ex_demo.zig):
- [Roadmap](https://github.com/FObersteiner/zdt/wiki/Roadmap)
- Contributions: Welcome!

### [Demo](https://github.com/FObersteiner/zdt/blob/master/examples/ex_demo.zig)

```zig
// need an allocator for the time zones since the size of the rule-files varies
Expand Down Expand Up @@ -69,7 +72,7 @@ See [changelog](https://github.com/FObersteiner/zdt/blob/master/change.log)

## Zig version

This library is developed with Zig `0.14.0-dev` aka 'master', might not compile with older versions. As of 2024-09-20, Zig-0.13 stable or higher should work.
This library is developed with Zig `0.14.0-dev` aka 'master', might not compile with older versions. As of 2024-10-01, Zig-0.13 stable or higher should work.

## IANA timezone database version

Expand Down
15 changes: 11 additions & 4 deletions lib/Datetime.zig
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ pub fn weekday(dt: Datetime) Weekday {
return std.meta.intToEnum(Weekday, dt.weekdayNumber()) catch unreachable;
}

pub fn monthEnum(dt: Datetime) Month {
return std.meta.intToEnum(Month, dt.month) catch unreachable;
}

/// Number of the weekday starting at 0 == Sunday (strftime/strptime: %w).
pub fn weekdayNumber(dt: Datetime) u8 {
const days = cal.dateToRD([3]u16{ dt.year, dt.month, dt.day });
Expand All @@ -497,10 +501,6 @@ pub fn weekdayIsoNumber(dt: Datetime) u8 {
return cal.ISOweekdayFromUnixdays(days);
}

pub fn monthEnum(dt: Datetime) Month {
return std.meta.intToEnum(Month, dt.month) catch unreachable;
}

/// Roll datetime forward to the specified next weekday. Makes a new datetime.
pub fn nextWeekday(dt: Datetime, d: Weekday) Datetime {
var daysdiff: i8 = 0;
Expand Down Expand Up @@ -582,6 +582,13 @@ pub fn fromString(string: []const u8, directives: []const u8) !Datetime {

/// Make a datetime from a string with an ISO8601-compatibel format.
pub fn fromISO8601(string: []const u8) !Datetime {
// 9 digits of fractional seconds and hh:mm:ss UTC offset: 38 characters
if (string.len > 38)
return error.InvalidFormat;
// last character must be Z (UTC) or a digit
if (string[string.len - 1] != 'Z' and !std.ascii.isDigit(string[string.len - 1])) {
return error.InvalidFormat;
}
var idx: usize = 0; // assume datetime starts at beginning of string
return try Datetime.fromFields(try str.parseISO8601(string, &idx));
}
Expand Down
5 changes: 5 additions & 0 deletions lib/Formats.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! common datetime formats

pub const DateOnly = "%Y-%m-%d";
pub const TimeOnly = "%H:%M:%S";
pub const DateTime = "%Y-%m-%d %H:%M:%S";
Loading

0 comments on commit 99e1d05

Please sign in to comment.