couchdb date format automatically updated - javascript

Whenever I update any key in couchdb document, it updates existing all date keys in milliseconds formats.
Example:
created_at: 2013-07-09T09:25:00
to
created_at: /Date(1373354700000)/
do you ever come across this issue?

The reason of this conversion can be find here.
If you're using JavaScriptSerializer then it converts the DateTime object as the format
/Date(ticks)/
But It will not convert DateTime string to ticks.
Whereas, if you're using JsonSerializer then you will find the date and time in correct format no matter of object or string type.
Note: JavaScriptSerializer is too slow in as compared to JsonConvert. You can have performance comparison of different serialization.

Related

Ignore timezone offset while converting date - javascript

I have a WCF REST service that returns date in below format:
/Date(1401993000000+0530)/
The value of this date on the server is
6/6/2014 12:00:00 AM
I want to parse this in my javascript code in UTC value.
I tried manually removing the "+0530" string and parsing it to date but it gives "Invalid Date".
I also tried adding the timezone offset as per this post but it gives incorrect value.
How can I parse this?
This format is commonly referred to as an "ASP.NET JSON Date" - because it first emerged from the JavaScriptSerializer and DataContractJsonSerializer classes used in ASP.NET and other parts of .NET. However, it was heavily criticized, and ultimately deprecated in favor of the standard ISO 8601 format, which is the default in the Json.Net library used in most modern .NET code. You'll still see it in WCF, and in older versions of ASP.NET MVC.
This format has two main variations:
/Date(1401993000000)/ - A timestamp alone
/Date(1401993000000+0530)/ - A timestamp with an offset
You will occasionally see the forward slashes escaped with backslashes, as in \/Date(1401993000000)\/, depending on how it was generated. This should be tolerated by parsers, but should not be depended upon.
In both formats shown, the timestamp portion is intended to represent the number of milliseconds since the Unix Epoch, which is 1970-01-01 00:00:00.000 UTC.
I say "intended", because it is possible in .NET to have a DateTime with DateTimeKind.Unspecified, which can't possibly be mapped back to UTC. In this case, the serializer will act as if it had DateTimeKind.Local. The output will then reflect the value adjusted to UTC in the computer's local time zone, along with the computer's UTC offset for that point in time. Ideally, you should not rely on this behavior, as you will get different results from computers in different time zones.
When an offset is present in the output string, it is in +HHmm/-HHmm format, with positive values falling East of GMT - the same direction as the ISO 8601 standard. However, unlike ISO 8601, the value portion is not adjusted for that offset. It remains UTC-based.
In other words:
/Date(1401993000000)/ = 2014-06-05T18:30:00Z
/Date(1401993000000+0530)/ = 2014-06-05T18:30:00Z + +0530 = 2014-06-06T00:00:00+05:30
Because of this, the offset portion is extraneous when using this value to create a JavaScript Date object - since a Date object wraps a timestamp in UTC, and has no provision for retaining a provided offset.
You can certainly break out the string into its parts and use them yourself,
but instead consider using Moment.js for parsing this string. It understands the format natively, and can give you back an object that retains knowledge of the offset.
var m = moment.parseZone("/Date(1401993000000+0530)/");
m.format() // "2014-06-06T00:00:00+05:30"
If you were looking for a Date object, you can certainly call m.toDate(). The resulting Date object will have the same UTC timestamp, but due to how the Date object works, any local-time functions will only use the offset of the host environment.
In other words, with output of a Date object, the +0530 part of your input becomes useless. You might have well have parsed /Date(1401993000000)/.
You can use Moment JS, one of the better ways to play with datetime in JavaSCript. Lot of functions
https://momentjs.com/timezone/
See the edited message, without momentjs:
var data = [ {"id":1,"start":"/Date(1401993000000+0530)/"} ];
var myDate = new Date(data[0].start.match(/\d+/)[0] * 1);
myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60 * 1000);
alert(myDate);

To clear up some doubts about moment.js

I got stuck in my project, due to some doubts related to moment.js. I'll state some conclusions here I made during writing backend on project, and please can someone correct me if something is wrong?
For example, if I get datetime string from fronted, in format:
"THU 18 MAR 2017 09:20 AM", I should create moment object passing this string to it and corresponding token "ddd DD MMM YYYY HH:mm A" as passed string is not in standard ISO 8601 format.
var datetime = moment(datetimeFromFrontend, "ddd DD MMM YYYY HH:mm A");
Now I have moment object that can be formated in way I want, calling format() function on moment object.
If I want to do some manipulations with datetime generally (for example, compare to today's datetime, or compare only time part), is it mandatory to convert all manipulating datetimes, times or whatever to moment object with same format and using isBefore, isEqual and so on, or can I somehow compare them using >, <, <=, =< ?
If I need to compare (>, < etc) datetime or just time part with value retrieved from SQL database (which is DATETIME or TIME data type), should I pass both comparing values to moment object, convert them in same format and then do manipulations?
And how to save to SQL database column which is DATETIME, or TIME type? Should do some transforms from moment object to string using format()? SQL will automatically convert passing string to corresponding data type?
Example:
var now = moment();
I assume that "now" can't be passed to sql query directly as it is moment object, it should be converted to string (and rely on SQL automatic conversion from string/nvarchar to datetime) or should I save it as moment().toDate() ?
If I need to compare (>, < etc) datetime or just time part with value retrieved from SQL database (which is DATETIME or TIME data type), should I pass both comparing values to moment object, convert them in same format and then do manipulations?
You might want to lookup the docs for that
You have Query functions that can compare moments and even Date objects, for example, this is the entry for the .after function
moment().isAfter(Moment|String|Number|Date|Array);
as you can see, you can pass anything to .isAfter and it will do that job for you
moment().isAfter(new Date(2017, 2, 4))
// true
moment(new Date(2016, 2, 4)).isAfter(new Date(2017, 2, 4))
// false
Of course the easiest way to compare >, < or === is to get the timestamp using Date::getTime, but that's ugly code
And how to save to SQL database column which is DATETIME, or TIME type? Should do some transforms from moment object to string using format()? SQL will automatically convert passing string to corresponding data type?
I think it depends how you SQL works and how your server communicates to it, ORACLE, you should refer to any documentation about storing date objects inside your sql, eventually dates and formats are all about making unix-timestamps human readable/understandable.
I assume that "now" can't be passed to sql query directly as it is moment object, it should be converted to string (and rely on SQL automatic conversion from string/nvarchar to datetime) or should I save it as moment().toDate() ?
Ask yourself what kind of benefits you or anyone that may use you API will gain from getting agnostic Date objects from your DB rather then just plain strictly formatted strings?

How to work with datetimes betwixt javascript, JSON, and python, and mongodb?

Colleague and I have scabbed together a little app that uses a bunch of JS in the browser, and communicates with a Tornado (Python3) server via JSON, the server uses mongodb as a backing store for persistent data. This is a sort of first for both of us.
What we're finding difficult is how to interchange datetime information between the JS and Python. We do believe that we should use UTC times for everything. JSON doesn't have a datetime literal, so we have to encode it somehow. We naively (?) used the JS notion of milliseconds from 1970 and have been sharing big integers back and forth. So the JS code might get the current utc now time with something like:
var newTime = new Date().getTime();
On the Python3/mongo side, we'd like to use real datetime objects, so we convert that with something like:
datetime.datetime.utcfromtimestamp(jsMilliseconds / 1000)
But then when we have to send date back, said Python3 object only has a timestamp() method. And round tripping that doesn't seem to create the same time. So we've been frustrated with this.
What we're looking for is for someone with experience to give us a good set of idioms to use here. Should we be using strings, instead of the ms integers when passing back and forth with JSON? What are the recommended methods to use on both sides to go between that format? Or should we stick with the integers and which methods should we be using then?
There are obviously a lot of requirements to consider when dealing with time. However, in the case you want to maintain a Date/Time to be displayed to user in their time zone and use mongo/python/java/javascript, I've used ISO 8601 date formats and always store UTC (Zulu) time. Also, if you truly want to maintain the actual time that something occured, not only do you need to store the "date/time" you need to also store the "timezone" (for example IANA timezone string) where the event occurred.
For a lifetime a reading, you can search for "date time best practices". This answer has a good start on discussion: Daylight saving time and time zone best practices
Alright, now to the code (all of this can be found readily on the internet if you search for
" parse||output ISO 8601 parsing" (e.g. "python parse ISO 8601 date string"):
JSON - on the wire between JavaScript and Python backend send a complex (can be simple if you have no need to preserve time zone) object with ISO-8601 formatted string and string to store time zone string:
{
"dateTime": "1970-07-10T12:00:00.047Z",
"timeZone": "America/New_York"
}
Java Script
a. read datetime string JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse
var d = Date.parse("2011-04-26T13:16:50Z");
b. write datetime string How do I output an ISO 8601 formatted string in JavaScript?
var date = new Date();
date.toISOString(); //"2011-12-19T15:28:46.493Z"
Python
a. read datetime string How do I translate a ISO 8601 datetime string into a Python datetime object?
import dateutil.parser
yourdate = dateutil.parser.parse(datestring)
b. write datetime string Python - Convert date to ISO 8601
import dateutil.parser as parser
date.isoformat()
Mongo - store datetime as native datetime field http://docs.mongodb.org/manual/reference/mongodb-extended-json/#date
a. store datetime string (notice "$date" and that datetime is in ZULU/UTC (denoted by 'Z')):
"dateTime" : { "$date" : "1970-07-10T13:00:00.047Z"}
Reference:
1. IANA TimeZone Databasehttp://en.wikipedia.org/wiki/Tz_database
2. The google calendar API (event resource) can be used as an example for RFC 3339, as well (see start/end): https://developers.google.com/google-apps/calendar/v3/reference/events

Why can't JSON.parse() parse what date.toJSON() creates?

Tested using chrome Canary
I can convert a date to JSON:
> (new Date()).toJSON()
"2012-05-03T22:27:30.530Z"
I can convert it back to a Date:
> typeof (new Date("2012-05-03T22:27:30.530Z"))
object
Why can't I parse it as a Date using JSON.parse()? JSON.parse returns a string, not a Date:
> JSON.parse('{"DateValue":"2012-05-03T22:27:30.530Z"}').DateValue
"2012-05-03T22:27:30.530Z"
Because a Date is not a valid type in JSON. JSON only knows about strings, numbers, booleans, arrays, and generic objects (associative arrays/hashes/maps/dictionaries/pick-your-favorite-name). When you convert anything else to JSON, you get one of the above - which means if you want to get the "something else" back out as the type it started as, the receiver has to do some extra work to recreate it.
There are JSON libraries that abstract that work away, and include an extra attribute indicating what class something is, so if the receiver is using the same library they'll get that type back, but that's still the same work, just hidden by the library.
Because in the JSON, the date is a string, in the same way new Date("2012-05-03T22:27:30.530Z") parses a string. You're expecting JavaScript to know that the string in the JSON is a date.
You need to pass the JSON parsed string to the date object to get a date back out:
var date = new Date(JSON.parse('{"DateValue":"2012-05-03T22:27:30.530Z"}').DateValue);
The .toJSON method is only there to return a value that can be representated in JSON. Yet JSON does not know about data types, and is not possible to store object instance information (like the prototype) in a JSON string.
So, the toJSON method of Date could return a number (e.g. the Unix timestamp), a plain object with properties representing year, month, day etc. (not so good because not parsable with the Date constructor) or - what happens to be - a string, in here the ISO time format. With that, you can use new Date(JSON.parse(stringified_date)) to create a new Date object.
If you would delete Date.prototype.toJSON;, JSON.stringify(new Date) would result in "{}".

What is the "right" JSON date format?

I've seen so many different standards for the JSON date format:
"\"\\/Date(1335205592410)\\/\"" .NET JavaScriptSerializer
"\"\\/Date(1335205592410-0500)\\/\"" .NET DataContractJsonSerializer
"2012-04-23T18:25:43.511Z" JavaScript built-in JSON object
"2012-04-21T18:25:43-05:00" ISO 8601
Which one is the right one? Or best? Is there any sort of standard on this?
JSON itself does not specify how dates should be represented, but JavaScript does.
You should use the format emitted by Date's toJSON method:
2012-04-23T18:25:43.511Z
Here's why:
It's human readable but also succinct
It sorts correctly
It includes fractional seconds, which can help re-establish chronology
It conforms to ISO 8601
ISO 8601 has been well-established internationally for more than a decade
ISO 8601 is endorsed by W3C, RFC3339, and XKCD
That being said, every date library ever written can understand "milliseconds since 1970". So for easy portability, ThiefMaster is right.
JSON does not know anything about dates. What .NET does is a non-standard hack/extension.
I would use a format that can be easily converted to a Date object in JavaScript, i.e. one that can be passed to new Date(...). The easiest and probably most portable format is the timestamp containing milliseconds since 1970.
There is no right format; The JSON specification does not specify a format for exchanging dates which is why there are so many different ways to do it.
The best format is arguably a date represented in ISO 8601 format (see Wikipedia); it is a well known and widely used format and can be handled across many different languages, making it very well suited for interoperability. If you have control over the generated json, for example, you provide data to other systems in json format, choosing 8601 as the date interchange format is a good choice.
If you do not have control over the generated json, for example, you are the consumer of json from several different existing systems, the best way of handling this is to have a date parsing utility function to handle the different formats expected.
When in doubt simply go to the javascript web console of a modern browser by pressing F12 (Ctrl+Shift+K in Firefox) and write the following:
new Date().toISOString()
Will output:
"2019-07-04T13:33:03.969Z"
Ta-da!!
From RFC 7493 (The I-JSON Message Format ):
I-JSON stands for either Internet JSON or Interoperable JSON, depending on who you ask.
Protocols often contain data items that are designed to contain
timestamps or time durations. It is RECOMMENDED that all such data
items be expressed as string values in ISO 8601 format, as specified
in RFC 3339, with the additional restrictions that uppercase rather
than lowercase letters be used, that the timezone be included not
defaulted, and that optional trailing seconds be included even when
their value is "00". It is also RECOMMENDED that all data items
containing time durations conform to the "duration" production in
Appendix A of RFC 3339, with the same additional restrictions.
Just for reference I've seen this format used:
Date.UTC(2017,2,22)
It works with JSONP which is supported by the $.getJSON() function. Not sure I would go so far as to recommend this approach... just throwing it out there as a possibility because people are doing it this way.
FWIW: Never use seconds since epoch in a communication protocol, nor milliseconds since epoch, because these are fraught with danger thanks to the randomized implementation of leap seconds (you have no idea whether sender and receiver both properly implement UTC leap seconds).
Kind of a pet hate, but many people believe that UTC is just the new name for GMT -- wrong! If your system does not implement leap seconds then you are using GMT (often called UTC despite being incorrect). If you do fully implement leap seconds you really are using UTC. Future leap seconds cannot be known; they get published by the IERS as necessary and require constant updates. If you are running a system that attempts to implement leap seconds but contains and out-of-date reference table (more common than you might think) then you have neither GMT, nor UTC, you have a wonky system pretending to be UTC.
These date counters are only compatible when expressed in a broken down format (y, m, d, etc). They are NEVER compatible in an epoch format. Keep that in mind.
"2014-01-01T23:28:56.782Z"
The date is represented in a standard and sortable format that represents a UTC time (indicated by the Z). ISO 8601 also supports time zones by replacing the Z with + or – value for the timezone offset:
"2014-02-01T09:28:56.321-10:00"
There are other variations of the timezone encoding in the ISO 8601 spec, but the –10:00 format is the only TZ format that current JSON parsers support. In general it’s best to use the UTC based format (Z) unless you have a specific need for figuring out the time zone in which the date was produced (possible only in server side generation).
NB:
var date = new Date();
console.log(date); // Wed Jan 01 2014 13:28:56 GMT-
1000 (Hawaiian Standard Time)
var json = JSON.stringify(date);
console.log(json); // "2014-01-01T23:28:56.782Z"
To tell you that's the preferred way even though JavaScript doesn't have a standard format for it
// JSON encoded date
var json = "\"2014-01-01T23:28:56.782Z\"";
var dateStr = JSON.parse(json);
console.log(dateStr); // 2014-01-01T23:28:56.782Z
JSON itself has no date format, it does not care how anyone stores dates. However, since this question is tagged with javascript, I assume you want to know how to store javascript dates in JSON. You can just pass in a date to the JSON.stringify method, and it will use Date.prototype.toJSON by default, which in turns uses Date.prototype.toISOString (MDN on Date.toJSON):
const json = JSON.stringify(new Date());
const parsed = JSON.parse(json); //2015-10-26T07:46:36.611Z
const date = new Date(parsed); // Back to date object
I also found it useful to use the reviver parameter of JSON.parse (MDN on JSON.parse) to automatically convert ISO strings back to javascript dates whenever I read JSON strings.
const isoDatePattern = new RegExp(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/);
const obj = {
a: 'foo',
b: new Date(1500000000000) // Fri Jul 14 2017, etc...
}
const json = JSON.stringify(obj);
// Convert back, use reviver function:
const parsed = JSON.parse(json, (key, value) => {
if (typeof value === 'string' && value.match(isoDatePattern)){
return new Date(value); // isostring, so cast to js date
}
return value; // leave any other value as-is
});
console.log(parsed.b); // // Fri Jul 14 2017, etc...
The prefered way is using 2018-04-23T18:25:43.511Z...
The picture below shows why this is the prefered way:
So as you see Date has a native Method toJSON, which return in this format and can be easily converted to Date again...
In Sharepoint 2013, getting data in JSON there is no format to convert date into date only format, because in that date should be in ISO format
yourDate.substring(0,10)
This may be helpful for you
I believe that the best format for universal interoperability is not the ISO-8601 string, but rather the format used by EJSON:
{ "myDateField": { "$date" : <ms-since-epoch> } }
As described here: https://docs.meteor.com/api/ejson.html
Benefits
Parsing performance: If you store dates as ISO-8601 strings, this is great if you are expecting a date value under that particular field, but if you have a system which must determine value types without context, you're parsing every string for a date format.
No Need for Date Validation: You need not worry about validation and verification of the date. Even if a string matches ISO-8601 format, it may not be a real date; this can never happen with an EJSON date.
Unambiguous Type Declaration: as far as generic data systems go, if you wanted to store an ISO string as a string in one case, and a real system date in another, generic systems adopting the ISO-8601 string format will not allow this, mechanically (without escape tricks or similar awful solutions).
Conclusion
I understand that a human-readable format (ISO-8601 string) is helpful and more convenient for 80% of use cases, and indeed no-one should ever be told not to store their dates as ISO-8601 strings if that's what their applications understand, but for a universally accepted transport format which should guarantee certain values to for sure be dates, how can we allow for ambiguity and need for so much validation?
it is work for me with parse Server
{
"ContractID": "203-17-DC0101-00003-10011",
"Supplier":"Sample Co., Ltd",
"Value":12345.80,
"Curency":"USD",
"StartDate": {
"__type": "Date",
"iso": "2017-08-22T06:11:00.000Z"
}
}
There is only one correct answer to this and most systems get it wrong. Number of milliseconds since epoch, aka a 64 bit integer. Time Zone is a UI concern and has no business in the app layer or db layer. Why does your db care what time zone something is, when you know it's going to store it as a 64 bit integer then do the transformation calculations.
Strip out the extraneous bits and just treat dates as numbers up to the UI. You can use simple arithmetic operators to do queries and logic.
The following code has worked for me. This code will print date in DD-MM-YYYY format.
DateValue=DateValue.substring(6,8)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(0,4);
else, you can also use:
DateValue=DateValue.substring(0,4)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(6,8);
I think that really depends on the use case. In many cases it might be more beneficial to use a proper object model (instead of rendering the date to a string), like so:
{
"person" :
{
"name" : {
"first": "Tom",
"middle": "M",
...
}
"dob" : {
"year": 2012,
"month": 4,
"day": 23,
"hour": 18,
"minute": 25,
"second": 43,
"timeZone": "America/New_York"
}
}
}
Admittedly this is more verbose than RFC 3339 but:
it's human readable as well
it implements a proper object model (as in OOP, as far as JSON permits it)
it supports time zones (not just the UTC offset at the given date and time)
it can support smaller units like milliseconds, nanoseconds, ... or simply fractional seconds
it doesn't require a separate parsing step (to parse the date-time string), the JSON parser will do everything for you
easy creation with any date-time framework or implementation in any language
can easily be extended to support other calendar scales (Hebrew, Chinese, Islamic ...) and eras (AD, BC, ...)
it's year 10000 safe ;-) (RFC 3339 isn't)
supports all-day dates and floating times (Javascript's Date.toJSON() doesn't)
I don't think that correct sorting (as noted by funroll for RFC 3339) is a feature that's really needed when serializing a date to JSON. Also that's only true for date-times having the same time zone offset.

Categories