I am getting a problem while using moment.js with Norwegian locale. The date is containing double dots after month, like below
des.. 2017
I have found that moment-with-locales.js in line 1009 contains a list of short dates. Months which contains a dot (.) results in a invalid date. Because dot (.) is also used as a separator in date format.
There is a ongoing discussion on github.
Is there any better solution to handle this?
Related
I'm using OffsetDateTime class for parsing date from the database.
Why the date contains 'T' ??
Example: 2018-01-01T12:00:00.000Z
I can understand the format is <<Date>>T<<Time>>.<<Offset>><<TimeZone>>. But still, I don't understand why 'T' is used in between.
Thanks in advance
ISO 8601
2018-01-23T12:00:00.000Z
That means noon on the twenty-third of January in 2018 in UTC.
That is one of the standard formats defined by ISO 8601. These formats are designed for exchanging date-time values as text, easy to parse by machine, easy to read by humans across cultures. The ISO 8601 is a modern standard, supplanting formats seen in various earlier Internet standards. ISO 8601 is also being adopted in various industries beyond information technology.
The T in the middle separates the date portion from the time-of-day portion.
After the period (FULL STOP) is any number of digits for the fractional second. The standard prefers the use of COMMA, but people in the US often use the period.
The Z on the end is pronounced “Zulu” and means an offset-from-UTC of zero hours-minutes-seconds, or +00:00:00.
why 'T' is used in between
A letter was desired to avoid the use of SPACE characters to make recognition and parsing easier. As to why T, you’d have to ask the authors of the standard. I can only guess that the letter “t” was chosen for the word time in English, temps in French, etc.
The use of Z for an offset of zero is taken from common usage in aviation and military.
I highly recommend you use these ISO 8601 formats when storing, writing, exchanging, and logging date-time values as text. These formats are wisely designed to be simple and practical. They avoid the use of SPACE character, and avoid extensive use of English and any other language.
The java.time classes built into Java 8 and later use these formats by default when parsing and generating strings.
Instant.now().toString()
2019-08-27T20:15:21.005946Z
The java.time.ZonedDateTime class extends the standard wisely to append the name of the time zone in square brackets.
Instant instant = Instant.parse( "2019-08-27T20:15:21.005946Z" ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
zdt.toString(): 2019-08-28T08:15:21.005946+12:00[Pacific/Auckland]
Week
You asked:
Am I able to use 'W' instead of 'T' in my given example
No. When representing a moment, you must use a T between the date and time.
A W is used in another of the ISO 8601 formats, when representing a week date of a week-based year.
String output = zdt.toLocalDate().format( DateTimeFormatter.ISO_WEEK_DATE ;
2019-W35-3
For working with standard weeks, use the YearWeek class from the ThreeTen-Extra project that extends java.time functionality.
LocalDate ld = zdt.toLocalDate() ;
YearWeek yw = YearWeek.from( ld ) ;
ld.toString(): 2019-08-28
yw.toSting(): 2019-W35
LocalDate ld = zdt.toLocalDate() ; // Extract just the date without the time-of-day and without time zone.
See all that code above run live at IdeOne.com, except for YearWeek.
I am using the following code to parse dates, but it doesn't seem to work following formats 04 Aug 2017, 05-Aug-2017. Basically if the date is starting with 0 and we use a number of order formats together as below.
For below example, it throws output as 2014-04-20 UTC
library(lubridate)
dateStr <- "04-Apr-2014"
newdate <- parse_date_time(dateStr,orders =c("m d y","m-d-y","m/d/y","d m y","d-m-y","d/m/Y","d B y","d-B-y","d/B/y","B d y","B-d-y","B/d/y","y m d","y d m","y-m-d","y-d-m","y/m/d"),locale = "eng")
newdate
This is not a bug, more perhaps a side-effect of a "feature".
This comes down to the "relaxed" extensions that lubridate supports. For instance, m in the strict sense is a month number, but lubridate also expands to include abbreviated and full month names. Similarly, y is typically just the two-digit year, but is extended to include the century as well. (Similar to poly-morphic code, this flexibility comes at a cost: the potential for getting things wrong.)
Further, lubridate::parse_date_time tries to be smart by supporting heterogenuous date-times (from its man-page), so "09-01-01" and "090101" will parse to be the same thing.
In this case, since you use m and y, it tries to go with numeric only, and matches the 14 to y, ignores all non-numeric (since you suggested numeric), and sees 20 as the day. If you remove all month-leading formatting strings, it no longer tries to find that order of things.
So, mitigation against this problem:
reduce the number of possible orders= formats; the more you offer, the more it can go wrong
remove all formatting strings that start with "m", only feasible if you are certain your dates will not start with month
if you have some control over the types of strings you are getting, then restrict the use of numeric-versus-named months, perhaps giving the parser a better shot
don't use parse_date_time, perhaps the other functions (e.g., dmy or not-lubridate)
file a bug if you feel strongly enough about this, though you leave yourself open to it when you try "a gazillion" formatting strings
I wrote a data frame in CSV format with R and opened it with Excel. Then I converted it to an Excel Workbook and made some edit on it.
When I imported that Excel file in R again, the date column looked like this. (Few are in numbers and few are dates.)
Date
39387
39417
15/01/2007
16/01/2007
I tried to change the format with Excel but failed. General or number option in Excel format generate the number like I mentioned which is in no way related to the date.
It seems all four of your example are in respect of dates in January (11th and 12th for the first two), that the Excel involved has been configured to expect MDY (rather than DMY as popular in UK for example) and its date system to ‘1900’, and that the CSV has written the dates as 'conventional' dates rather than date index numbers.
So what Excel saw first was:
11/01/2017
12/01/2017
15/01/2017
16/01/2017
intended to represent the 11th, 12th, 15th and 16th of January. However, because expecting MDY Excel has interpreted (coercing the Text to date index) the first two entries as November 1 and December 1. For ‘months’ 15 and 16 it did no interpretation and just reported the text as in the CSV.
The coercion is automatic with no option to turn it off (nor 'reversed' with a change of format). Various ways to address this (common) issue are mentioned in the link kindly provided by #Gerard Wilkinson. I am not providing a full solution here since (a) some things are under user control (eg the ‘1904’ system is an option, as is the choice whether MDY or DMY) and (b) the preferred route will depend to some extent on how often required and what the user is most familiar with.
I'm creating book writing software.
The problem is, when user create story that happen say in year 200 BCE [ CE / BCE wiki], how to store this date in SQLite so I can sort it like normal DateTime.
The documentation for the built-in date functions says:
These functions only work for dates between 0000-01-01 00:00:00 and 9999-12-31 23:59:59.
However, SQLite does not have a separate data type for dates; it just uses numbers or strings, and interprets them as dates only when you apply a date function to them.
If you do not actually need to use the SQLite date functions, you can use any type and format, as long as it sorts correctly.
Strings like yyyy-mm-dd do not sort correctly for BCE dates, so you have to use numbers (Julian days, or Unix timestamps, or any other format).
Dates in DB2 AS/400 are an integer, containing the number of days since sometime around the turn of the 20th century.
Question 1: Does anyone know the IBM DB2/AS400 "zero" date? e.g.:
12/30/1899
12/31/1899
1/1/1900
Question 2: Given an "AS/400" date (e.g. 40010) how can you convert that to a CLR DateTime?
DateTime d = new DateTime(40010); //invalid
Some other "zero" dates are:
OLE Automation: 12/30/1899
SQL Server: 1/1/1900
I don't think AS/400 dates are stored internally as some number of days from an epoch date1 (this is the more common term for what you are calling "zero date"). As Tracy Probst said, this is definitely NOT what date fields in native AS/400 physical files look like.2
But that's immaterial if whatever method you are using to extract the data is giving it to you as the number of days since an epoch. Ideally, you should find out what the intended date is by looking directly at the AS/400, or asking someone who can. If the date on the AS/400 is 2009-07-30 and what you are getting is 40022, then you can be pretty confident the epoch date is Jan 1, 1900. If you are getting 40024, then the epoch is Dec 30, 1899. (Though it's of course best to compare a bunch of dates, preferably from different years to guard against possible use of Julian dates.)
Also, as Tracy commented on his own answer, it's exceedingly common for dates to be stored in generic numeric fields (which is what I would guess if your retrieval method is reporting Decimal as the data type), in which case it really has nothing to do with DB2's internal date format anyway. You should be aware that by far the most common date formats stored in AS/400 numeric fields are the following, or variations thereof:
yyyymmdd (Gregorian, ISO 4-digit year)
mmddyy (Gregorian, U.S. 2-digit year)
yyyyddd (so-called Julian, 4-digit year)
yyddd (so-called Julian, 2-digit year)
yymmdd
cyymmdd (IBM's crazy invention with century flag)
The ddd in the Julian dates is the number of days from the beginning of year. The c in IBM's crazy date is 0 for 19yy or 1 for 20yy. I have not heard of anyone who stores days-since-epoch on "The Four Hundred" but maybe you've encountered a convert from another platform. The mainframe heritage of the AS/400 strongly favors human-readable dates.
1The AS/400 (now called IBM i) does have its own data type for dates, and this data type actually does consist internally of a number of days from an epoch. But that epoch is many thousands of years in the past, not somewhere near the turn of the 20th century, and not even near the beginning of the Common Era. IBM likes to call this number of days the Scaliger number, but for most people who study this stuff, it's called the Julian Day Number. As you may have noticed from the main part of my answer, IBM uses the word "Julian" to mean something completely different (and not even related to the Julian calendar). Namely, IBM's so-called "Julian date" is really the ordinal date from ISO 8601.
2The internal format of the date data type is very low-level and mostly hidden from the user (including most programmers). The DSPPFM command, which ostensibly shows the "actual contents" of a file, is at least one step "too late": the value it reports has already been converted from the internal, 4-byte "Scaliger number" to a human-readable form.
Question 1:
I have no idea what the start date is for DB2. Google isn't very helpful anyway. Don't you have any sample data you could use to figure it out?
Update: are you sure the date is stored as a number of days? I found this page that suggests otherwise.
Question 2:
Assuming 1900-01-01 as the start date in this example, where days is the AS/400 date value.
DateTime myDate = new DateTime(1900, 1, 1).AddDays(days);
I don't know the answer for 1. But for 2, you can do something like this:
private DateTime AS400 = new DateTime(1900, 1, 1);
...
DateTime myClrDT = AS400.AddDays(days);
Question 1:
As far as I can tell, there is no "zero date" in an AS/400 phsyical file. If I do a DSPPFM on a phsyical file with a timestamp field in it, the value is stored as a readable timestamp in the format yyyy-MM-ddhh.mm.ss. For example: "2005-08-0207.06.33" for 08/02/2005 at 7:06:33 AM. There can be a zero-date within a particular programming language and that's really where you need to focus. The AS/400 ODBC driver returns the date in a SQL_TYPE_TIMESTAMP field.
Question 2:
It should be as simple as:
DateTime d = Convert.ToDateTime(reader["DateField"]);
I invite other C# experts to edit the response with better C# code.
I've just 5 months of experience in DB2(working on AS400), so i just can show you something
about the way we work with dates. It's true that we consider the 'zero' date in our calculation of the date fields. In our system, the 'zero' date =12/31/1971 0:00.
I don't know if this is the 'only' 'zero' date in AS400.
In our system files, the date we use is stored as the number of days from the 'zero' date(length=5).
So, every time we have to get the date field, from a specified file, we convert this field to get the date in the format : dd/mm/yyyy or yyyy-mm-dd(it depends from the environment where we execute the query). The function is:
date(field+719892), where field is the field where we store the date and 719892 is the number of days we add after each unconverted date we use(it seems like it is the number of days between x-12/31/1971, you can calculate x).
I'll give you on more example:
select date(15+719892) as date1 from library1.file1
The result is: date1=1972-01-15
marc_s had a comment that confused the "zero" dates with "minimum" dates in SQL Server. Just so everyone gets to see the example:
SELECT
CAST(0 AS datetime) AS dateTimeZero,
CAST(0 AS smalldatetime) AS smallDateTimeZero
dateTimeZero smallDateTimeZero
======================= ===================
1900-01-01 00:00:00.000 1900-01-01 00:00:00