I have been reading different articles on the said question yet i am unable to figure out what should be the best strategy to store the date in db.
I will be receiving the ISO8601 date via path-param in a rest call. What I have decided
Use Joda-Time to parse the date.
Extract UTC-0 time out of the date and the hours offset
Store UTC-0 in DateTime datatype in mysql db and store offset in varchar(5).
When I have to search something based on the date (an exposed rest api). I will use the search criteria (input date) extract the UTC-0 time and hours offset and compare the two columns in the db i.e. where table.dateInUTC0 = :inputDateInUTC0 AND table.hoursOffset = :inputHoursOffset
I am not sure about step 4. Am i doing i right ?
I am not sure about step 4. Am i doing i right ?
Really, it depends on what you are trying to do.
If you want the search to only match if the searcher is using the same timezone as the original data, then you are doing it right.
If you don't want that, you are doing it wrong.
Ask yourself this: If you enter the same date / time in your local time zone and UTC (or some other time zone), do they mean the same thing for clients of your server? Should they?
Related
While writing integration test I was expecting a hardcoded date in the response.
Basically I hardcoded expected date value '2020-11-10T00:00:00.000-05:00'
and ran new GregorianCalendar(2020, 10, 10).getTime()
When I put and assert and run it locally it passes, however when the same code was pushed to bamboo build server the actualValue it generated was'2020-11-10T00:00:00.000Z' and so my test failed.
Why the same calendar.getTime generating two different times, is it because the server machine is configured to be on GMT?
Can I do something to have them the same time or any other workaround?
NOTE: Making it string or comparing dates without time is not an option here, as I am using Spring MockWebServiceServer, where in I must hardcode the responseXML and specify date, something like this in Enum.
REQUESTAUTOMATESETTLEMENTWORKCASE("<aut:AutomateSettlementWorkcaseRequest xmlns:aut=\"http://www.abcd.com/abcd/workflow/services/workcase/model/AutomateSettlementWorkcase_1_0_0\">" +
" <aut:customerAccountId>5049903033584324</aut:customerAccountId>\n" +
" <aut:settlementDate>2020-11-10T00:00:00.000-05:00</aut:settlementDate>\n" +
" </aut:AutomateSettlementWorkcaseRequest>"),
The "-5" part in your input data is throwing it off... ideally you should specify the time zone when constructing the calendar, and then set it to 5am UTC (for example). Basically, 2020-11-10T00:00:00.000-05:00 is the same instant as 2020-11-10T05:00:00.000Z.
Now, what we don't know is whether it's important to you that you preserve the offset from UTC. If it is, you need to set an appropriate time zone in the calendar - one which has the same rules as whatever's generating your input data. If it isn't, I'd use UTC and set the time appropriately.
I would personally recommend using Joda Time instead of Calendar and Date though - it's a much better date and time API. No 0-based months, for starters :)
I have a Joda Date Time object that contains date and time fields and I wish to extract the date and time portions into 2 different sql date and time objects (java.sql.). I thought converting the DateTime to milliseconds and storing it in the respective sql objects would do the trick however it produces calculation errors further upstream in my app logic as one is === to the other.
Best way I've found to do this so far is what I've described in my comment on the question and then convert back to sql time using:
new java.sql.Date(locDate.toDateTime(LocalTime.MIDNIGHT).getMillis()));
new java.sql.Time(locTime.toDateTimeToday().getMillis()) );
Couldn't find anything in the DateTime object API to extract the respective parts.
This question has few sub-questions!
What is best data type for storing date?
java-s Date, or just long - in miliseconds, formated String?
Client/Server time-zone problem
a) How to show date on client side (correct time zone)
b) If client inserts date, server needs to insert date in servers timezone or better fixed app timezone? (correct api?)
Sorting is easy with long data type, but is it working with Date?
Manipulating (for example select records for last 4 days, or between two dates, etc...).
Is there any good manual for this topic!
Currently, I am using long for date data type, but it somehow does't feel right (for example browsing in admin console is confusing).
Thanks!
java.util.Date is a supported type
How you show this to the user is a more generic java problem. All dates are stored in UTC. I suggest you take a look at joda-time for handling timezones and dates.
Yes, sorting of Date objects is supported in queries etc.
Filtering is also supported, eg, date > yesterday && date < today. Don't forget to bear in mind there are limitations when you impose filters. For example, those inequality filters can only apply to one property at a time. See restrictions on queries
For example, when I extract from a database a Date() variable, it contains a date with "+04:00" shift.
According to my locale's settings.
So, UTC time is "ourTime" MINUS 4 hours.
Then, a user tells where he/she is from. Now, we need to save his/her shift.
LET'S SAY it is -01:00.
And finally, this user tells us where's he/she is heading, let's say this place has a time shift of +05:00.
How do we save this town's or place's time shifts in the DB so that according to where he/she's from
we could calculate the time difference with our current locale?
Also, date save light things, how do we work with them?
You don't.
As long as you're using java.util.Date objects (or java.sql.Date, or java.sql.Timestamp) the database will contain UTC time, that's what java.util.Date holds internally.
You need to format and/or parse these dates according to local timezone. Take a look at SimpleDateFormat for more information. Of course, if you have dates in the database that you manually parsed, then you may be SOL.
Which is the most beneficial in Java and a DB for DateTime? (Using JodaTime as Date)
(DateTime object (Java) + TIMESTAMP (DB) ) VS (Milliseconds long (Java) + BIGINT(DB)
for the use of DateTime information in Java Web application backed by an underlying Database
Areas of interest
manipulating, processing and memory usage in Java
saving using efficient storage space in
a MySQL database
ease of porting a BIGINT/TIMESTAMP column to other DBs
ease of searching the DB for a BIGINT/TIMESTAMP or between two BIGINTs/TIMESTAMPs
E.g. Say I had an event with a start & end DateTime.
Is it faster to search for events on dates using BIGINT in the DB than TIMESTAMPS
I might be swapping the underlying DB as scalability and retrieval issues arise.
Would saving the DateTime as a TIMESTAMP in a MySQL DB lead problems when porting to another DB like Oracle?
I currently use the Joda DateTime in java then storing the millisecond of that value.
When retrieving it, I convert the milliseconds back to a DateTime object and display it.
I’m always using the “milliseconds since 1970” approach. This way I don’t have to worry about which timezone the date belongs to because the date in the database is always UTC.
There are really two questions here. First, what abstraction should you use in Java to represent time? Joda Time is definitely better than java.util.Date. If you are wondering whether to simply use a long -- I imagine you can't get away with that if you need to do any date manipulation or comparison. So, Joda Time.
And then it is definitely best to use TIMESTAMP for this in MySQL as it will be nearly identical storage-wise and MySQL will treat the value appropriately, as a date, when you want to use date functions on the column. JDBC drivers will also understand that it should be mapped to a date type.
I can't imagine you will have trouble porting a date type, represented correctly as a date in your schema, to another database, should you need to. I can imagine problems if you treat the date type as a bigint, which is less correct.
So, simply choose the most correct types here. I doubt there is any performance win available from choosing a less suitable type anyway.
Of course it depends on what you want to do with the data, but I would recommend using the DB's native type for time/date (whatever that may be) for storage in the DB. That is the standard for databases, and most date/time functions in DBs expect data in that form.
Special note about MySQL:
While you can use TIMESTAMP for date/time values, be aware that TIMESTAMP cannot record dates earlier than 1970-01-01. So while it's ok for dates close to "now" (such as creation/modification dates), it is not appropriat for possibly historical dates such as date of birth. So only use TIMESTAMP if you are completely certain you will never need historical dates.