Hello, my name is Dmitry Karlovsky and I ... are very old. The years are not the same to easily understand the intricacies of tricky interfaces. I want something relatively simple, but also powerful enough not to feel like a cripple, who barely writes the simplest program.
In any application, sooner or later there is a need to work with time: parse, somehow modify, calculate something, serialize. Date and time are quite complex things that adapt to the solar, lunar and terrestrial cycles at the same time. Moreover, there may be a different number of days in a year, and a different number of hours in a day, even
in a minute, not always 60 seconds . Because of this, working with time requires a heightened accuracy from the programmer and anyway
bugs will emerge for a very long time .
No, I am too old to consider years as milliseconds - soon my age will amount to billions of seconds already. It's time to take advantage of something higher. The fact that our ancestors called the standard
ISO8601 , but many still do not know what it is and through what place it should be used.
')
Then you will learn how I got rid of hemorrhoids by changing the city minivan to a sports bike :-)
In any JS engine there is a standard api for working with time - Date. Let its name not mislead you: Date objects are not dates, but the most time stamps (moments) measured in milliseconds from the beginning
of the UNIX epoch . The API provides an object interface that allows you to get various information for the moment: from the time components (year, month, day, hour, minute, second) to the day of the week corresponding to it. Unfortunately, this information is available either for local time or for UTC. If you need other time zones, then I have bad news for you - Date can only parse the iso8601 line like "2015-07-20T00: 22: 32 + 01: 00", get a timestamp from it and happily forget about time zones as about a terrible dream. Well, damn it with him, if not for a couple of nuances:
1. Sometimes the time zone matters. For example, when you write a server application that must understand when the client has morning, and when it is evening, when it is yesterday, and when it is tomorrow. That is, you need the opportunity to complete work with any time zone.
2. Sometimes the time zone only interferes. For example, when you draw a calendar and operate with dates regardless of time, the intervention of time zones
can easily spoil your blood . That is, you need the opportunity not to specify certain components of time, if they are not necessary.
In ISO8601, if you write "2015-07-20", then this is July 20 in any time zone. The moments of the beginning and end of this day in different time zones will nevertheless be different. If you use “new Date ('2015-07-20') ', then you will receive a time stamp of the beginning of this date in UTC:“ 2015-07-20T00: 00: 00.000Z ”, and if you write the seemingly equivalent code“ new Date (2015, 06, 20) ", the result will be" 2015-07-19T21: 00: 00.000Z ". Date developed spontaneously, like all api in javascript, so you should not be surprised at such a
variety and
many ways to do the same thing, but a little differently, as well as a bunch of useless methods .
The popular
MomentJS library tries to solve the messy interface problem while doubling the number of methods you will never use. No, well, really, why would anyone in a sober mind and healthy memory use
ASP.NET JSON Date of the form "/ Date (1198908717056-0700) /"? And despite the fact that it implements a lot of necessary things that are not present in the native Date at all, it still has the same kind of trauma, as it is just a wrapper over the native api, which provides only a time stamp abstraction. So “moment ('2015-07-20')” will return the label “2015-07-19T21: 00: 00.000Z” with all the problems arising from this.
Another birth injury common to both api is object mutability. If you are going to somehow change the object, then you must remember to clone it, otherwise somewhere in the other end of the application you may suddenly have everything broken.
But the saddest thing is that MomentJS without plug-ins weighs as much as 100 kilobytes and at the same time
slows down as a twin dangling at near-light speed , not even looking at
fifty-fold acceleration :
if (0 < m.year() && m.year() <= 9999) { if ('function' === typeof Date.prototype.toISOString) {
Well, do you feel a burning sensation just below your back? Then proceed to the treatment.
First of all, you should decide how to store data inside. Date can be specified with time and without. Time can be specified with or without offset. Both the date and the time can be indicated both in full and cropped form (year-month, for example, or hour-minute). That is, any component of time may be missing if its value does not make sense. To code July 2015, we need only two components: a year, a month, and nothing else. That is, it makes sense to store components in separate fields, which will slightly increase memory consumption, but on the other hand will have a beneficial effect on the speed of work.
Further, it is worthwhile to properly understand the
format iso8601 . After all, there is no need to reinvent the wheel, when there is a good standard which already provides a lot. In particular, it allows you to describe time points with different accuracy (from milliseconds to years), time durations in various units of measurement (from seconds to years), time intervals in various forms (start-end, start-duration, end-duration) and even repeated intervals (but they are not very suitable, unfortunately).
Now we are ready to write the
$ mol_time library, which provides 3 functions that create objects corresponding to their names:
$ mol_time_moment ,
$ mol_time_duration, interval . Each of them is capable of accepting parameters for construction in various JSON views: as an iso8601 string or as a configuration object of the form {name_component: value_component}. In addition, moments can be created from native Date objects and timestamps, and durations from among the milliseconds.
To illustrate, let's calculate how many years I have already turned.
Math.floor( new $mol_time_interval( '1984-08-04/' ).duration.count( 'P1Y' ) )
Let's complicate the task: what day of the week will it be when I hit a billion seconds?
new $mol_time_moment( '1984-08-04' ).shift({ second : 1e9 }).toString( 'WeekDay' )
What time is it in Japan?
new $mol_time_moment().toOffset( '+09:00' ).toString( 'hh:mm' )
And let's print all the days of the week in the current month in order:
let current = new $mol_time_moment().merge({ day : 0 , hour : 0 , minute : 0 , second : 0 }) const end = current.shift( 'P1M' ) while( current < end ) { console.log( current.toString( 'DD - WD' ).toLowerCase() ) current = current.shift( 'P1D' ) }
Further, I will probably leave you with the
documentation on $ mol_time and will look forward to harsh criticism, because since I started using this library, I had pretty gray hair on my head, the skin on it became smooth and silky, and without hemorrhoids life has become even a little boring :-)