My first serious project was Chrono a Timestamps, Calendars, and Timezones 
library for Nim.

[https://github.com/treeform/chrono](https://github.com/treeform/chrono)

I have become much better at Nim than when I first wrote it. I recently went 
over the project and wanted to share things that I have improved.

1\. Github actions. Github actions are easy to set up and make sure your 
project/library stays tested. I now use this as a standard for all my Nim 
projects: 
[https://github.com/treeform/chrono/blob/master/.github/workflows/build.yml](https://github.com/treeform/chrono/blob/master/.github/workflows/build.yml)
 It just runs nimbe test which means it will probably work for your project too 
without changes.

2\. Turns out nimbe test just runs all files that start with test in the test 
directory. Easy. No need to configure how the tests are to be run.

3\. When I was new to Nim I wanted everything static and pointerless. For this 
I thought not using a string but instead using this packed string in an array 
was smarter. But now I learned - just use a string, it's fine. Don’t over 
complicate your code.

4\. I did not want to use json. I wanted to use binary formats .. compressed 
binary formats. If you are storing nested data just use json. It’s simply an 
eraser. I removed a bunch of the code for creating and loading the binary 
formats and my life became simpler. I mostly use this library in JS mode so 
binary format was not really needed.

5\. Always put your code into a src dir. Even though nimble supports not having 
src dir, it’s just better in every way.

6\. Use nimpretty. It’s easy to use and formats your code so it’s more inline 
with the Nim standard. I feel tools like nimpretty from bikeshedding discussion 
on how code should be formatted. It just does its thing. I wish it did more 
though.

7\. Write good tools with command line parameters. In my earlier version I had 
people modify the src file to run it. That was just stupid. I added parameters 
to generate and now you can generate a timezone dump of any time slice you want.
    
    
    nim c -r tools/generate.nim json --startYear:2010 --endYear:2030 
--includeOnly:"utc,America/Los_Angeles,America/New_York,America/Chicago,Europe/Dublin"
    
    
    Run

Some things have not changed and I still firmly stand by on:

A. For a time library, the lowest building block should be the timestamp of a 
single float64, not a complex calendar object. You should store timestamps and 
transfer timestamps. Calendar should only be used in time calculation like next 
month, previous week, 60 days from now… its a display/compution object that 
should be short lived.

B. Normalizing a calendar is an easy way to work with it. Instead of not 
allowing a month of 60 days… just allow it and have a function that normalizes 
it. It just spills the days into next month. It’s very easy to do calendar math 
this way, as you can overflow calendar fields for a short time.

C. You need to make the user aware of timezone files. On some OSs there is a 
location where you can get timezone information that is up to date, but that is 
not the case on Windows and JS-Browser mode. That is why I provide a way to 
generate timezones from the source and ship them with your JS or native app. 
It’s an important feature for me.

D. Adding a timezone to a calendar is complex. There needs to be two functions 
… I call apply and shift. Both functions will make your calendar have the new 
timezone offset. 
    
    
    applyTimezone: "1970-05-23T21:21:18Z" -> "1970-05-23T14:21:18-07:00"
    shiftTimezone: "1970-05-23T21:21:18Z" -> "1970-05-23T21:21:18-07:00"
    
    
    Run

But apply will not shift your time stamp, while shift will.

Reply via email to