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.