I need to pass datetimes between an android client, a python server and a mysql server.
It should work the following:
the android client sends the exact time from the client to the cherrypy python server (I guess the datetime object should be sent as a string?)
the server has to parse this string into something useful to work with as a datetime object
Now there a two cases:
the datetime object should be written into a mysql database (there is an attribute of type DATETIME in the related database table)
the server should retrieve a datetime from the mysql database and compare it with the parsed datetime object
After some background processes finished their work with the python datetime objects as input parameters, a new datetime object should be passed back to the android client
Does anyone know some good solution for solving these problems?
The best format for transferring datetime values is the ISO 8601 standard; they come in the format YYYY-mm-ddTHH:MM:SS+tz:tz, where the T is optional.
Python's datetime.datetime class can parse these with a simple extra module (see How to parse an ISO 8601-formatted date?). Output is just as easy with the .isoformat() method.
MySQL's DATETIME column type only deals with UTC values, but by default accepts ISO 8601 datetime strings (with a space instead of a T), so you'd have to cast your datetime objects to UTC (example with iso8601 module mentioned above):
import iso8601
utciso8601 = dt.astimezone(iso8601.iso8601.UTC).isoformat(' ')[:19]
I'd insert the timezone offset into the database too; simply use the tzname() method to retrieve it from the datetime object, then parse it out again when loading from MySQL with the iso8601.iso8601.parse_timezone() function.
# insertion:
cursor.execute('INSERT INTO dates VALUES(?, ?)', utciso8601, dt.tzname())
# querying
for row in query:
timezone = iso8601.iso8601.parse_timezone(row[1])
utcdt = iso8601.parse_date(row[0])
dt = utcdt.astimezone(timezone)
I don't know how well Android deals with dates and times, but surely it can handle ISO 8601 formats just fine.
Related
The issue has in two parts.
I want to know what is the best way to access the Oracle TIMESTAMP WITH TIMEZONE column in an entity class. I've checked around and found that this DB data type maps to TimeStamp datatype in Java but this doesn't store timezone information.
Issue is the DB is not saving data as 2017-08-10 10:30:20.15 -07:00 which is how I want it saved, it is converting it to the server's timezone and saving the value. Do I have to turn off some settings to get the DB to work the way I want?
So, My initial idea was to use the ZonedDateTime data type since it can capture the date properly in the format which I want, which is DateTimeFormatter.ISO_OFFSET_DATE_TIME ( aka yyyy-mm-dd'T'HH:MM:ss TZM:TZ). But this doesn't map to the DB data type and I lose Timezone info when converting to some other datatype.
I have a spring-data-rest API and I create a query like so:
#Query("SELECT at FROM Transaction at WHERE at.transactionDate BETWEEN :start AND :end")
Page<AssetsTransaction> findAllByDates(
#Param("start") Instant start,
#Param("end") Instant end,
Pageable pageable);
Where Transaction.transactionDate is an Instant type.
how I should pass a date from a javascript app?
Typically timestamps are stored/transferred/etc. in one of two ways:
UNIX timestamps
This is just a number representing the number of seconds from a fixed time in the past (known as the UNIX epoch).
Java has the Instant#getEpochSecond() method to obtain this value, and the Instant.ofEpochSecond() static method to create an Instant object from a timestamp.
Javascript has the Date type which can be instantiated from a timestamp (new Date(timestamp * 1000)), and transformed into a timestamp with difficulty.
ISO 8601 strings
This is just regular ASCII text with a standardised format, for example:
2018-11-21T22:25:58+00:00
You gain the advantage of timezone support with this method.
Java uses Instant#toString() to get an ISO 8601 string, and this slightly more verbose method to convert back:
Instant.from(DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(string));
Javascript does not have native support for timezones, but it can still produce an ISO-compliant string with Date#toISOString() and parse it back with the static Date.parse().
Whichever way you go, you may wish to use an additional library on the javascript side to gain more control over your timestamps, if this is important to you.
I have java.util.Date field in my document class.
E:g:
#Document(collection = "testdoc")
public class TestDoc {
#Id
String id;
Date startDate;
}
Even if I set the Date with UTC and IST, it always save in my collection as below,
"startDate" : ISODate("2015-08-21T18:30:00.000Z")
How can I save the time zone also in mongo collection? What does Z stand in this case?
The 'Z' signifies that the time is stored in UTC. Mongo internally converts all local representations of time in UTC before storing. However, one suggestion would be to store the time along with the timezone which is received from your application. You can later reconstruct the local time from the UTC time and the timezone in your application logic.
Please go through this link. They have given an example on how to model local time data using JavaScript.
https://docs.mongodb.com/v3.2/tutorial/model-time-data/
Do the conversion before storing and save as UTC always. Then reconvert it in the timezone you want before displaying.
If you desperately want to store the timezone with the offset you may have to deal with it as a separate string in db, but it cannot go with date field for MongoDB.
As currently MongoDB doesn't allow saving of timezone.
Below is the open JIRA issue or the same.
https://jira.mongodb.org/browse/SERVER-6310
Dates in MongoDB are stored in UTC. There isn't timestamp with a timezone data type like in some relational databases. Applications that need to access and modify timestamps, based on local time, should store the timezone offset together with the date and offset dates on an application level.
In the MongoDB shell, this could be done using the following format with JavaScript:
let now = new Date();
db.page_views.save({date: now,
offset: now.getTimezoneOffset()});
Then you need to apply the saved offset to reconstruct the original local time, as in the following example:
let record = db.page_views.findOne();
let localNow = new Date( record.date.getTime() - ( record.offset * 60000 ) );
I guess here you'll find a good guideline how to handle timestamps in different scenarios for different data language independent.
As it's recommendet in the document, ALWAYS use UTC to save the data, even it is local timezone. If necessary, save the time zone in a seperate field ( JSON or xml) and follw the format guideline ISO 8601. ( like you did but there are many possible representations)
As far as I know, correct me if i'm wrong, JSOn does not deal with specific date formats but JS does. Microsoft docs recommends the followind format bases on ECMA YYYY-MM-DDTHH:mm:ss.sssZ this
The Z in the Timestamp shows that it's UTC format with zero offset +00:00
if nothing else is added.
If you want to use the "Z" notation, you have to add or substract the offset within the timestamp instead of writing the zero-offset and add the offset at the end.
I recommend you to follw the w3c guideline because it covers different scenatios for different time saving usecases.
Hope this helps
I have to insert data(which is also containing the timezone, i.e. 2013-01-19 00:00:00 +0530) which is in String form and the datatype of the column is DATETIMEOFFSET. I have tried both java.util.date and sql.date but could not find any solution.
If you're using the Microsoft JDBC driver, you can use the DateTimeOffset class, constructing instances with the valueOf method.
You'll need to parse the value out into local time and offset (in order to pass the two parts separately) but that shouldn't be too bad using SimpleDateFormat. (The Z format specifier in SimpleDateTimeFormat will handle offsets like +0530.) Alternatively, use Joda Time which will make life easier still, as it will allow you to parse to a DateTime which lets you get the offset as well as the local time in one go. I would personally use Joda Time and create a method to convert from a DateTime to a DateTimeOffset.
I am using Facebook graph API to retrieve user wall information. In that, I am getting the post created time value as:
created_time: "2012-04-19T09:00:02+0000"
Can anyone suggest me how to convert this time to UTC or epoch value in Java?
The format of date you receive is ISO 8601.
As described in Converting ISO8601-compliant String to java.util.Date (using Joda-Time):
DateTimeFormatter parser = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2012-04-19T09:00:02+0000";
System.out.println(parser.parseDateTime(jtdate));
You basically need to parse the ISO8601 date format. There are libraries out there that would do it for you or you can create your own parser (relatively simply), e.g.
http://www.java2s.com/Code/Java/Data-Type/ISO8601dateparsingutility.htm