Allow some exceptions / special cases in the date validation with moment.js - momentjs

We use moment.js as our date validation, and it works great.
We also use it in custom Angular controls, with date format strings. Very difficult stuff, but easy with moment.js.
However, we run in the situation that we want to allow '00-12-1980' as input for our date control (read below if you want to know why), where 00 is the day, and 12 is the month. Also '00-00-1980' and '00-00-0000' must be valid. (or 00/00/0000 if the format string is D/M/YYYY, etc)
Now in moment.js these dates are marked invalid, and I also didn't find any way to check these dates with moment.js with some sort of addition "Yeah, I know 00 is weird for a daynumber, but just allow it". Or say new moment('00-00-1980', 'D-M-YYYY') and then ask "what is the daynumber?" to do some validation later myself.
So without moment, I have to do all the parsing (including date format strings) myself, and that is a lot of work, and error prone too. So my question is: can I somehow work with moment.js and also allow these kind of dates?
So you wondered why we want to allow the odd dates of '00-00-1980'? It's becasue it's a search field, and the source system (official government sources) has these dates, from the goold old times when this input was allowed.

Related

Date strings as the ids in json-api

I'd like to find out is it correct according to json-api standards. I'd like to have item like calendar_day at the top level. Is it correct that data would contain items like
{:data=>[{:id=>"2020-04-15", :type=>:calendar_day, :attributes=>{:date=>"2020-04-15"}} ...
and than some relationships for each calendar_day item.
Worth to mention that calendar_day is not actually the "real" record in my db, it's just the app concept although I'v got a model defined to make json-api serializer work with it easy.
Even though there isn't a standard format for dates in json api specification, ISO 8601 is recommended. As far as that goes, your example is fine.
All id keys must have string values.
Having said that, you have to be careful since datestrings aren't unique by themselves. You could use a timestamp just to be sure that you have the right document. With that, you can get any date info that you need down to the millisecond.

how to create an user-key from a date?

I maintain a WCF service. Since it's been decided to put a version of the service in a public server, for demo/testing purposes, it's needed to add some kind of security regarding who can access the functions. So, I thought about adding a key to each function that the client must supply in order to verify his access.
But, as the software is a licensed one (by a period of time), and it's installed locally on the customer's server when it's bought, I thought that an elegant solution could be to embed the expiration date into the key, so I don't have to put some license file or something.
I'm thinking about, giving a certain date (the expiration date) I could generate a short string (like 8 characters, letters and numbers) that appears random to the user and that he can't alter into a valid one but which I could decode and get the date that it was used to generate it.
I thought about encrypting a plain date, but the algorithms I know generate a super user-unfriendly results.
I appreciate any suggestions, thank you very much!
You could try changing the date to a single number, such as the number of days since 4 July 2017, or some semi-random starting date. If that is too transparent, then use some type of format preserving encryption to encrypt the day count to the same number of digits using a standard key.

Moment JS - parse UTC and convert to Local and vice versa [duplicate]

This question already has answers here:
moment.js - UTC does not work as i expect it
(2 answers)
Closed 8 years ago.
I have gone through the documentation and am a tiny bit confused about how to proceed.
There are similar questions, but none talk about parsing particular dates received in formats and swapping between local and utc dates.
I receive a local datetime, local datetime format and need to generate utc datetime from it in a particular format and this is how I think I should do it. moment(dateTime,localDateTimeFormat).utc().format(specifiedFormat);
I receive utc datetime in a particular format and have to generate locale specific datetime in a particular format. How do i do it?
moment.utc(utcDateTime, utcDateTimeFormat).toDate(); gives me javascript date i believe. How do I format it then?? Do I have to create a new moment using the generated Date object?
Another thing I could do would be getting the timezone and then formatting. I wonder if I am taking the wrong route here. Please help.
On Item 1 - Yes, that's one way to do it. However, if the output format is just going to be an ISO8601 UTC timestamp, then you can call toISOString directly on the original moment. Since UTC is implied by the output, it would be redundant to call utc() again.
On Item 2 - Just like the utc() function, there's also a local() function. Once you have a moment object, you can use toDate or format or any other of the functions described in the documentation. No, you do not need to create a new moment using the generated date object.
moment.utc(utcDateTime, utcDateTimeFormat).local().format(specifiedFormat)
Again, there's more than one way to do things here. If the utcDateTime is already in ISO8601 format, and contains either a Z or an offset like -01:00, then that will be taken into account and you can simply do this:
moment(utcDateTime).format(specifiedFormat)
On the last item you mentioned about time zones, it's difficult to tell what you are asking. You should elaborate with specific details in a new question.

Consistent handling of DateTimes in different RDBMSs

I'm planning a distributed system of applications that will communicate with different types of RDBMS. One of the requirements is consistent handling of DateTimes across all RDBMS types. All DateTime values must be at millisecond precision, include the TimeZone info and be stored in a single column.
Since different RDBMS's handle dates and times differently, I'm worried I can't rely on their native column types in this case and so I'll have to come up with a different solution. (If I'm wrong here, you're welcome to show me the way.)
The solution, whatever it may be, should ideally allow for easy sorting and comparisons on the SQL level. Other aspects, such as readability and ability to use SQL datetime functions, are not important, since this will all be handled by a gateway service.
I'm toying with an idea of storing my DateTime values in an unsigned largeint column type (8 bytes). I haven't made sure if all RDBMS's in question (MSSQL, Oracle, DB2, PostgreSQL, MySQL, maybe a few others) actually /have/ such a type, but at this point I just assume they do.
As for the storage format... For example, 2009-01-01T12:00:00.999+01:00 could be stored similar to ?20090101120000999??, which falls in under 8 bytes.
The minimum DateTime I'd be able to store this way would be 0001-01-01T00:00:00.000+xx:xx, and the maximum would be 8000-12-31T23:59:59.999+xx:xx, which gives me more than enough of a span.
Since maximum unsigned largeint value is 18446744073709551615, this leaves me with the following 3 digits (marked by A and BB) to store the TimeZone info: AxxxxxxxxxxxxxxxxxBB.
Taking into account the maximum year span of 0001..8000, A can be either 0 or 1, and BB can be anywhere from 00 to 99.
And now the questions:
What do you think about my proposed solution? Does it have merit or is it just plain stupid?
If no better way exists, how do you propose the three remaining digits be used for TimeZone info best?
One of the requirements is consistent handling of DateTimes across all RDBMS types.
Be aware that date-time handling capabilities vary radically across various database systems. This ranges from virtually no support (SQLite) to excellent (Postgres). Some such as Oracle have legacy data-types that may confuse the situation, so study carefully without making assumptions.
Rather than establish a requirement that broadly says we must support "any or all database", you should get more specific. Research exactly what databases might realistically be candidates for deployment in the real-world. A requirement of "any or all databases" is naïve and unrealistic because databases vary in many capabilities — date-time handling is just the beginning of your multi-database support concerns.
The SQL standard barely touches on the subject of date-time, broadly defining a few types with little discussion of the nuances and complexities of date-time work.
Also be aware that most programming platforms provide atrociously poor support for date-time handling. Note that Java leads the industry in this field, with its brilliantly designed java.time classes. That framework evolved from the Joda-Time project for Java which was ported to .Net platform as NodaTime.
All DateTime values must be at millisecond precision,
Good that you have specified that important detail. Understand that various systems resolve date-time values to whole seconds, milliseconds, microseconds, nanoseconds, or something else.
include the TimeZone info and be stored in a single column.
Define time zone precisely.
Understand the difference between an offset-from-UTC and a time zone: The first is a number of hours-minutes-seconds plus-or-minus, the second has a name in format Continent/Region and is a history of past, present, and future changes to the offset used by the people of a particular region.
The 2-4 letter abbreviations such as CST, PST, IST, and so on are not formal time zone names, are not standardized, and are not even unique (avoid them).
Since different RDBMS's handle dates and times differently, I'm worried I can't rely on their native column types in this case and so I'll have to come up with a different solution.
The SQL standard does define a few types that are supported by some major databases.
TIMESTAMP WITH TIME ZONE represents a moment, a specific point on the timeline. I vaguely recall hearing of a database that actually stored the incoming time zone. But most, such as Postgres, use the time zone indicated on the incoming value to adjust into UTC, then store that UTC value, and lastly, discard the zone info. When retrieved, you get back a UTC value. Beware of tools and middleware with the confusing anti-feature of applying a default time zone after retrieval and before display to the user.
TIMESTAMP WITHOUT TIME ZONE represents a date with time-of-day, but purposely lacking the context of a time zone or offset. Without a zone/offset, such a value does not represent a moment. You could apply a time zone to determine a moment in a range of about 26-27 hours, the range of time zones around the globe.
There are other types in the standard as well such as date-only (DATE) and time-only (TIME).
See this table I made for Java, but in this context the column of SQL standard types in relevant. Be aware that TIME WITH TIME ZONE makes no sense logically, and should not be used.
If you have narrowed down your list of candidate databases, study their documentation to learn if they have a type akin to the standard types in which you are interested, and what the name of that type is (not always the standard name).
I'm toying with an idea of storing my DateTime values in an unsigned largeint column type (8 bytes).
A 64-bit value is not likely appropriate. For example, the java.time classes use a pair of numbers, a number of whole seconds since the epoch reference of first moment of 1970 in UTC, plus another number for the count of nanoseconds in the fractional second.
It is really best to use the database's data-time data types if they are similar across your list of candidate databases. Using a count-from-epoch is inherently ambiguous, which makes identifying erroneous data difficult.
Storing your own count-from-epoch number is possible. If you must go that way, be sure the entire team understands what epoch reference was chosen. At least a couple dozen have been in use in various computing systems. Beware of staff persons assuming a particular epoch reference is in use.
Another way to define your own date-time tracking is to use text in the standard ISO 8601 formats. Such strings will alphabetically sort as chronological. One exception to that sorting is the optional but commonly used Z at the end to indicate an offset-from-UTC of zero (pronounced “Zulu”).
The minimum DateTime I'd be able to store this way would be 0001-01-01T00:00:00.000+xx:xx,
Taking into account the maximum year span of 0001..8000
Are you really storing values from the time of Christ? Is this software really going to be around executing transactions for the year 8000?
This is an area where the responsible stakeholders should define their real needs. For example, for many business systems you may need only data from the year of the product's launch and run out only a century or two into the future.
The minimum/maximum value range varies widely between different databases. If you choose to use a built-in data type in each database system, investigate its limits. Some, for example, may go only to the year 2038, the common Y2038 problem.
To sum up my recommendation:
Get real about your date-time needs: min/max range, resolution, and various types (moment versus not a moment, date-only, etc.).
Get real about your possible databases for deployment.
If you need enterprise-quality reliability in a classic RDMS, your candidate list is likely only a few: Postgres, Microsoft SQL Server, Oracle, and maybe IBM Db2.
Keep this list of supported databases as short as possible. Each database you agree to support is a huge commitment, now and in the future.
Be sure your chosen database(s) have a database driver available for your chosen programming language(s). For example JDBC for Java.
If at all possible, use the built-in data types offered by the database.
Be sure you and your team understand date-time handling. Many do not, in my experience, as (a) the subject is rarely taught, and (b) many programmers & admins mistakenly believe their quotidian intuitive understanding of date-time is sufficient for programming work. (Ignorance is bliss, as they say.)
Identify other areas of functionality beyond date-time handling, and compare which databases support those areas.
I would suggest you to store the datetime information in milliseconds since 1970 (Java style) .
It's a standard way for storing datetime information, in addition it's more efficient in terms of space than your suggestion. Because in your suggestion some digits are "wasted" i.e. the month digits can store only 00-12 (instead of 00-99) and so on.
You didn't specify what is your development language but I am sure you can find many code snippets that transform date to milliseconds.
If you are developing in .NET they have a similar concept of ticks. (you can use this information as well)
Regarding the time zone,I would have add another column to store only the TimeZone indication.
Remember that any format you choose should maintain consistency between two dates, i.e. if D1 > D2 then format(D1)>format(D2) , this way you can query the DB for changes since some date, or query for changes between two dates

Override DateTime serialization for ASP.NET WebMethod parameters

I am working on cleaning up a bug in a large code base where no one was paying attention to local time vs. UTC time.
What we want is a way of globally ignoring time zone information on DateTime objects sent to and from our ASP.NET web services. I've got a solution for retrieve operations. Data is only returned in datasets, and I can look for DateTime columns and set the DateTimeMode to Unspecified. That solves my problem for all data passed back and forth inside a data set.
However DateTime objects are also often passed directly as parameters to the web methods. I'd like to strip off any incoming time zone information. Rather than searching through our client code and using DateTime.SpecifyKind(..) to set all DateTime vars to Undefined, I'd like to do some sort of global ASP.NET override to monitor incoming parameters and strip out the time zone information.
Is such a thing possible? Or is there another easier way to do what I want to do?
Just to reiterate -- I don't care about time zones, everyone is in the same time zone. But a couple of users have machines badly configured, wrong time zones, etc. So when they send in July 1, 2008, I'm getting June 30, 2008 22:00:00 on the server side where it's automatically converting it from their local time to the server's local time.
Update: One other possibility would be if it were possible to make a change on the client side .NET code to alter the way DateTime objects with Kind 'Undefined' are serialized.
I have dealt with this often in many applications, services, and on different platforms (.NET, Java, etc.). Please believe me that you do NOT want the long term consequences of pretending that you don't care about the time zone. After chasing lots of errors that are enormously difficult and expensive to fix, you will wish you had cared.
So, rather than stripping the time zone, you should either capture the correct time zone or force a specific time zone. If you reasonably can, get the various data sources fixed to provide a correct time zone. If they are out of your control, then force them either to the server's local time zone or to UTC.
The general industry convention is to force everything to UTC, and to set all production hardware clocks to UTC (that means servers, network devices like routers, etc.). Then you should translate to/from the user's local time zone in the UI.
If you fix it correctly now, it can be easy and cheap. If you intentionally break it further because you think that will be cheaper, then you will have no excuses later when you have to untangle the awful mess.
Note that this is similar to the common issue with Strings: there is not such thing as plain text (a String devoid of a character encoding) and there is no such thing as a plain (no time zone) time/date. Pretending otherwise is the source of much pain and heartache, and embarrassing errors.
OK, I do have a workaround for this, which depends on the fact that I only actually need the Date portion of the DateTime. I attach this property to every Date or DateTime parameter in the system
<XmlElement(DataType:="date")>
This changes the generated wsdl to have the type s:date instead of s:dateTime. (Note that simply having the type of the .NET method parameter be a Date rather than a DateTime did NOT accomplish this). So the client now only sends the date portion of the DateTime, no time info, no time zone info.
If I ever need to send a Date and Time value to the server, I'll have to use some other workaround, like making it a string parameter.
I've had issues with the time zone information as well. The problem is I'm already providing the datetime fields in UTC. Then the serialization occurs and the local offset becomes part of the date/time. The dates/times for our vendor in a different timezone were pretty messed up. I got around this problem by using the tsql convert function on the datetime fields in my select statement I used to populate my datasets. This converted the fields to a string variable, which translates nicely to a datetime value automatically on the client side. If you just want to pass the date, you can use the 101 code to provide just the date. I used 126 to provide the date and time exactly how it appears in my database columns, with the timezone information stripped out.

Resources