Java datetime offsets/timezones class? - java

Ok this seems like its been done or handled somewhere in a class but not sure.
Problem is I have an event object with a start and end time. Then there is a main "day" object its compared against. Problem now is everything is UTC so it all works fine. So when user changes event object to use say eastern time with offset -5 on the event, its being compared against this day object with UTC time so of course you can get overlaps against the main "day" object because its two different timezones being compared against each other. This is of course bogus. Right now code is comparing date getTimeMillis to see if the end date time in millis is less than Day objects 23:59 UTC time or if the objects start time is greater than the Day object start time of 00:01.
So... is there a class out there that I can simply pass in the two date time's in millis, time zone and get a yes/no answer that handles all these offsets?
I of course could do it all manually using the "afterDate" or "beforeDate" stuff but was hoping there is some fancy built already to handle it all already?

Related

Do I have a way to avoid re-creating lots of String objects?

My project uses Javascript and Java (Android) for the client and Java for the backend.
When I started working on my project, I stored dates as days from epoch (long) and all was good. I then found out that my project doesn't work well with timezones. Suddenly dates were +1 -1 days off. Depending on the client's location in the world.
After a short investigation, I saw that the foolproof way to avoid it was to store the dates as String yyyy-MM-ddT00:00 so when using the Javascript's new Date(dateStr), it creates it correctly and all was good. Ofcourse I could store the dates as yyyy-MM-dd and just send it to the client as yyyy-MM-ddT00:00 but that won't solve the question I have.
After that, I was wondering whether Java (backend) is handled correctly. I use LocalDate when I want to "play" with dates and LocalDate.parse doesn't like yyyy-MM-ddT00:00 format, instead it works with yyyy-MM-dd so whenever I needed dates, I did LocalDate.parse(dateStr.substring(0,10)). LocalDateTime does work with yyyy-MM-ddT00:00 but I don't need the time part and it had its own issues, which I don't remember what they were at the moment.
So now I have a lot of String manipulation (inside loops) that actually creates more String objects. One can say it's not that much of a stress and I shouldn't pay attention to that but I want to make sure I'm not missing something and maybe there's another way (maybe silly enough that I've missed) to overcome this.
Thanks
Update: The events are stored from a different source and only the date itself is important so if an event happened on 2020-06-17, this is the date all users should see, no matter where they are.
I'm using new Date(dateStr) in Javascript. If dateStr is 2020-06-17, the date object uses the client's timezone and the date might be +-1 depending on the client's timezone. If dateStr is 2020-06-17T00:00 then the date object is created as expected no matter where the client is located.
Assuming the above, which I hope is clearer now, creating String objects over and over again is a memory stress that I should consider or is it something Java handles with no problem and I shouldn't worry about this?
My question was closed and I was told to edit it to be more focused. After editing my question, how can I re-open my question to answers?
As you have discovered, storing dates in terms of days since some epoch only works if everyone who uses your system is using the same time zone. If two different users in different time zones have a different idea about the date on which some event occurred (e.g., the person in New York says that the system crashed on Sunday night, but the the person in Hong Kong says it crashed on Monday morning), then you have to store the time zone in which the event occurred in order to show the date of that event accurately.
But if that's the situation you're in, why not just store the time zone along with the date? There's no compelling reason to combine the date and timezone into a string.
When you parse a ISO-formatted timestamp into a LocalDate using only the first 10 characters, be aware that you're losing the time zone information. Implicitly the LocalDate that you get is in the time zone of the original timestamp. So if the original timestamp is New York time, and you take the date part and add 1 day, then you'll get the next day in the New York time zone. But if you then take the date from a second timestamp, you can't compare it to the date you got from the first timestamp, in terms of determining if it represents the "same day." You can only test for "same day" if both dates are implicitly in the same time zone.
UPDATE
After reading your additional comments, I realize that what's happening is this. You have a date stored in your database, like 2020-06-15. You send that to the UI as the string '2020-06-15' and then do new Date('2020-06-15') and then you're surprised when you render the date in the UI and get June 14!
This is the transformation that happens:
The string '2016-06-15' gets parsed into a JavaScript Date representing midnight UTC on the June 15.
When you render the date, it gets converted into a string using the browser's local time zone, which (if you're in the United States) will give you June 14, because at midnight UTC on June 15 it's still June 14 in all time zones west of Greenwich.
You discovered that if you make the string "2020-06-15T00:00" that it works, because now JavaScript uses the browser's local time zone to parse the string. In other words, this string means midnight local time, not UTC, on June 15. So now the sequence is:
'2020-06-15T00:00' gets parsed using the local time zone and becomes June 15 4:00AM UTC.
When you render the date, it gets converted back to local time and is rendered as June 15.
The easiest way to avoid all this messiness is just to send the regular date string '2020-06-15' to the UI and render it using DateTimeFormat, specifying the time zone as UTC:
new Intl.DateTimeFormat('en-US', {timeZone: 'UTC'}).format(d)
Since dates in JavaScript are always UTC, and you're asking DateTimeFormat to output the date in UTC, no date shift occurs.
You could also use the Date methods getUTCFullYear, getUTCMonth, etc. to get the date components and format them however you like.
Once you're no longer sending dates back and forth with "T00:00" appended, you can just use LocalDate on the Java side.
Don't spend even a second worrying about the time required to manipulate strings. Think about the incredible amount of string manipulation that is necessary to build even a simple web page. A few more strings here and there isn't going to make a difference.

subtracting time in Java

Hello I am trying to create a teacher utility to port over to android OS. However I am running into a little trouble. I would like to create a class called Period. This class would contain the start and end time of that period. ie. Period one starts at 7:45 and ends at 8:45. I would also like to have a method for time left in period. for example it is now 8:10 and there are 35 minutes left. I am able to get the current time from System.currentTimeMillis(). However I am having trouble trying to figure out the best way to store the start and end time of the periods. i have taken a look at the Calendar class in Java and it seems like time is always tied to a date as well as a time. This does not seem to make seance for my application since the end time of the period happens on multiple days and not just on one particular date. Any help understanding this would be a great help. Thanks all
If your goal is to be able to compare the start and end time of the period with the current time, then you need a way to compute the date and time of the period's bounds for today.
So get a Calendar instance for today, set its time to 7:45, and compare the time of the calendar with the current time (same for the upper bound, of course).
To represent each bound, you could simply use an int for the hours and a second int for the minutes.
Check out the JodaTime library. The DateTime object has what you want.
Take a look at JodaTime.
Specifically, Period: http://joda-time.sourceforge.net/key_period.html
Calendar is a king of wrapper around the class Date which has mostly deprecated functions. I've heard that the JodoTime API is great for comparing two timestamps (http://joda-time.sourceforge.net/).
One way to store the start and end time for the periods would be to instantiate an ArrayList of dates so you can compare any given time to the lesson periods.
From what I can tell, you should store the time as a number of seconds (optionally milliseconds) from last midnight. Thus, your period one, 7.45, starts at 45*60 (45 minutes * 60 seconds per minute) + 7*60*60 (7 hours times minutes times seconds!) = 2 700 + 25 200 = 27 900.
Do the same calculation for your end date, and as long as they begin and end on the same day, you can easily subtract the difference and thus get the interval in between. If they do not happen on the same date, then Java's time and date classes are both excellent and a must. These classes essentially work the same algorithm, but do not count the seconds from "last midnight", instead they count the amount of milliseconds from the UNIX epoch time (1 January 1970).

Want to get minutes between two ISO 8601 times in two different time zones with joda

I have two strings from an android application in ISO 8601 format that I am trying to find the amount of minutes in between the two times. I was pointed to Joda Time which has been immensely helpful. However I have discovered now that one String is in UTC time and the other is my local time.
For example
"2012-05-11T02:34:18+00:00" is UTC and
"2012-05-10T21:44:09-05:00" is my local time
I have the following block of code which finds the number of minutes between the two times. My question is how can I go about to change the UTC time to my local time in order to get an accurate minutes in between
DateTime start = new DateTime(currentTime);
DateTime end = new DateTime(laterTime);
int min = Minutes.minutesBetween(start,end).getMinutes();
How do I go about to change the UTC time to my local time in order to get an accurate minutes in between?
My understanding is that you don't need to.
A DateTime instance represents a point on the time line, together with a timezone which controls how the time-point is mapped to a time frame (e.g. when you call the getters). When you take a time difference between a pair of DateTime instance, you get a measure representing the duration between two points on the timeline. This is independent of the timezones.
In other words, assuming that the two DateTime instances were created properly, your code should work as-is.

How to determine if a timestamp is within working hours?

Given a any unix timestamp (i.e. 1306396801) which translates to 26.05.2011 08:00:01, how can I determine if this is within a given timeframe (i.e. 08:00:00 and 16:00:00)?
This needs to work for any day. I just want to know if this timestamp is within the given time-interval, on any future (or past) day, the date is unimportant. I don't care if it is on the 25th or 26th, as long as it is between 08:00 and 16:00.
I am on the lookout for a java solution, but any pseudo code that works will be ok, I'll just convert it.
My attempts so far has been converting it to a java Calendar, and reading out the hour/min/sec values and comparing those, but that just opened up a big can of worms. If the time interval I want it between is 16.30, I can't just check for tsHour > frameStartHour && tsMin > frameStartMin as this will discard any timestamps that got a minute part > 30.
Thank you for looking at this :)
To clarify.
I am only using and referring to UTC time, my timestamp is in UTC, and the range I want it within is in UTC.
I think I understand what you want. You want to test for any day, if it's between 8am and 4pm UTC. Take the timestamp mod 24*3600. This will give you the number of seconds elapsed in the day. Then you just compare that it's between 8*3600 and 16*3600. If you need to deal with timezones, things get more complicated.
Given your timestamp (in seconds) and the desired time zone, Jodatime gives you the hour which leads you to a simple integer range check.
new org.joda.time.DateTime(timestamp*1000L, zone).getHourOfDay()
With java.util.* its more difficult.
If I understood you correctly, you only need to normalize your dates to some common value. Create three instances of Calendar - one with your time, but day, month, and year set to zero, and two with start and end of your timeframe, other fields also zeroed. Then you can use Calendar.after() and Calendar.before() to see if the date is within the range.
Your unix timestamp is an absolute time. Your time frame is relative. You need some kind of time zone information in order to solve this problem. I just answered some of this for PostgreSQL a few minutes ago. Hopefully that article is of use.
Convert the beginning of your range to a unix timestamp, and the end of your range to a unix tmestamp, then it's a simple integer check.

What is the Objective-C equivalent of the Java TimeZone?

What is the Objective-C equivalent of the Java TimeZone class?
The NSTimeZone class is the equivalent of the Java TimeZone class.
NSTimeZone, I believe. Can't say I've ever done any Objective-C myself, but it looks right...
Apple also has a (pretty short) article on using it.
It's quite likely that they won't be direct equivalents in every respect, of course... but if there's something you would use with Java's TimeZone which you can't figure out in NSTimeZone, ask about that specific call... and someone else can help you, I'm sure :)
EDIT: The purpose of a time zone class is to convert between local times in different time zones. For example, right now, it's 7.50pm for me - but it's 12.50pm for the person who I'm about to have a Skype call with. One option for representing dates and times is to always store them in UTC (which is sort of the "zero" of time zones) and then convert the UTC value into the "local" time for the user, e.g. for display purposes. That's not always the right option, but it's usually a good starting point.
At other times, you may have a local time and know person X's time zone - and want to convert it to person Y's time zone. It's usually easiest to do that by converting the local time to UTC (using X's time zone) and then to convert it back to local time using Y's time zone.
Time zones aren't nearly as straightforward as you might expect - mostly due to daylight savings. Oddities:
Local times which either don't exist, or occur twice, due to DST transitions
Time zones which change to DST at midnight, so that midnight doesn't always exist
Governments deciding to scrap (or introduce) DST at almost no notice
DST which isn't the normal "move an hour forwards". IIRC, Tibet was considering introducing DST of 1:15.
Historical changes to time zones
The list goes on.
NSTimeZone : http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSTimeZone_Class/Reference/Reference.html
Regards.

Categories