Giter VIP home page Giter VIP logo

zig-tzif's Introduction

Zig TZif

This repository implements TZif parsing, according to RFC 8536.

Usage

Take a look at the examples to get an idea of this library works. I recommend starting with the localtime example.

Add it as a package

To start, add zig-tzif to your build.zig.zon:

.{
    .name = "your-project",
    .version = "0.1.0",
    .dependencies = .{
        .tzif = .{
            .url = "https://github.com/leroycep/zig-tzif/archive/fdac55aa9b4a59b5b0dcba20866b6943fc00765d.tar.gz",
            .hash = "1220459c1522d67e7541b3500518c9db7d380aaa962d433e6704d87a21b643502e69",
        },
    },
}

Then, add zig-tzif to executable (or library) in the build.zig:

const Build = @import("std").Build;

pub fn build(b: *Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // Get the tzif dependency
    const tzif = b.dependency("tzif", .{
        .target = target,
        .optimize = optimize,
    });

    const exe = b.addExecutable(.{
        .name = "tzif",
        .root_source_file = .{ .path = "tzif.zig" },
        .target = target,
        .optimize = optimize,
    });

    // Add it as a module
    exe.addModule("tzif", tzif.module("tzif"));

    b.installArtifact(exe);
}

Useful functions

tzif.parseFile(allocator, filename) !TimeZone

tzif.parse(allocator, reader, seekableStream) !TimeZone

TimeZone.localTimeFromUTC(this, utc_timestamp) ?ConversionResult

Caveats

  • This library has not been rigorously tested, it might not always produce the correct offset, especially for time zones that have changed between different Daylight Savings schemes.
  • Does not support version 1 files. Files must be version 2 or 3.

zig-tzif's People

Contributors

leroycep avatar fobersteiner avatar nektro avatar

Stargazers

Malcolm Still avatar Chris Hart avatar Manu avatar  avatar Joachim Schmidt avatar Loris Cro avatar

Watchers

James Cloos avatar  avatar  avatar

Forkers

bcrist

zig-tzif's Issues

add more tests to POSIX TZ parser

zig-tzif/tzif.zig

Line 1140 in 3cc489a

// TODO : add more tests

Since I've been playing around with this a considerable amount now, I might as well go thought the chore of adding more tests, of some more obscure TZ strings. You can sign me up for this :)

Transition time UTC offset

.{ .utoff = -37886, .dst = false, .idx = 0 },

IIUC, a UTC offset takes effect at the transition time, not after the transition time. So to get the UTC offset for a given Unix time (s), you are looking for the next transition time less or equal to given Unix time.
In the test quoted above, the UTC offset seems to take effect after the transition time. However, Pacific/Honolulu did not experience LMT anymore at the first transition time, EX:

-2334101315 --> a second before the first transition: LMT
1896-01-13 11:59:59-10:31:26 -37886.0

-2334101314 --> at the transition
1896-01-13 12:01:26-10:30 -37800.0

-1157283000 --> next transition
1933-04-30 03:00:00-09:30 -34200.0
...and so on

Efficiency of epoch time calculations

// TODO: make more efficient?

addressing your comment, I think to make this more efficient, we could use days as base period, then add / subtract seconds where needed.

What I'm referring to here is Howard Hinnant's "date" algorithms - C++ library, explanations. For example the calculation of a transition time t from a given MonthWeekDay rule mwdand year could look like

// calculate unix time based on year and m/n/d from rule
// start with year-month, day = 1
t = @as(i64, unixdaysFromDate([3]u16{ year, mwd.m, 1 }));
// now find n'th weekday d
const first_wday = @mod((t + 4), 7);
var days_offset = mwd.d - first_wday; // days to add to reach first specified weekday in month
if (days_offset < 0) days_offset += 7;
var n = mwd.n;
if (mwd.n == 5 and days_offset + 28 >= days_in_month(mwd.m, std.time.epoch.isLeapYear(year))) n = 4;
t += (days_offset + 7 * (n - 1));
t *= std.time.s_per_day;
t += mwd.transition_time;
t -= offset; // correct for UTC offset *before* transition

unixdaysFromDate takes a triple year-month-day and returns days since the Unix epoch (Howard just calls it "days_from_civil"). zig-port. I've tested the applicability with an older version of your code, so the field names are different than in the current version etc. but... you get the point ;-)

UTC offset from POSIX rule

const result = try parsePosixTZ("MST7MDT,M3.2.0,M11.1.0");

POSIX rules give the standard offset in hours West of Greenwich. However, UTC offsets are "normally" presented in hours(:minutes) East of Greenwich, e.g. as specified by ISO8601, +01:00 means the datetime is 1 hour ahead (in Earth's rotation) of UTC.

Your parser currently returns seconds West, but incorrectly - if I didn't miss something! For example, America/Denver with rule "MST7MDT,M3.2.0,M11.1.0" is 7 hours (25200 s) behind (West of) UTC during standard time but only 6 hours (21600 s) behind UTC during DST since DST is +1 hour East.

I can have a deeper look into this and make a PR if you like.

still active?

Hi there @leroycep , I recently found your repo while looking how datetime (and time zone) handling is (or could be) implemented in Zig.

The last update to this repo was quiet some time ago, the language has evolved a bit since then and there's currently a TZif reader in the zig std lib. However, what I found to be missing there is a parser for the POSIX rule, found in the TZif v2+ footer. Since I found this kind of tricky, I was very happy to find your code :)

Do you have any plans with this repo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.