I am using Joda Time. I want to compare 2 dates/times A and B to determine if B has exceeded A.
Problem - When I logcat A it's not in UTC. When I logcat B it's in UTC. Therefore the comparison is not real.
A - A UTC time loaded from a file
B -The "System Time" in UTC
Code:
A - DateTime csvTime = new DateTime( inArray[5] ) ; //inArray[x] is loaded from a file and has this format: 2017-02-10T01:09:00Z
B - new DateTime(DateTimeZone.UTC)
Question - How do I load inArray[5] so it is truly in UTC and compares with B accurately?
Thanks in advance and yes I have looked at 100s of posts on this. I have yet to find a post that tells me the syntax for A above, how to store an external ISO 8601 format date in UTC internal. I have played around with TimeZone set default to force Joda/JVMP default TZ but that then puts me in a position of having to specify the TimeZone which I do not want to do.
If your input is already in UTC (trailing "Z") then I suggest you to parse it this way:
DateTime dt =
ISODateTimeFormat.dateTimeNoMillis().withOffsetParsed().parseDateTime(
"2017-02-10T01:09:00Z"
);
System.out.println(dt); // 2017-02-10T01:09:00.000Z
Otherwise you could tranform your A-DateTime to UTC by withZone(DateTimeZone.UTC).
Related
I am trying to fill 2 date objects, one in Local time and the other in UTC.
I AM NOT TRYING TO PRINT THE DATE AS A STRING IN GMT/UTC, please do not suggest DateFormatting, and dont say its a duplicate until you read the full question.
Local, I have no problem:
Date dateLocal = new Date();
The problem is I cant get the utcDate to be UTC.
Using a Calendar like so:
TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
Calendar c = new GregorianCalendar();
c.setTime(new Date());
c.setTimeZone(TimeZone.getTimeZone(utcTimeZone.getID()));
Date utcDate = c.getTime();
When debugged or submitted to the webservice, utcDate shows in my local timezone, instead of UTC.
Using Joda:
DateTime utcDateTime = DateTime.now(DateTimeZone.UTC);
Date utcDate = utcDateTime.toDate();
Same issue, utcDate when debugged/submitted to webservice is showing in local time.
Here is how the object looks when debugged:
This is an issue because this causes the webservice (which i have no access to) to think this time is UTC, so when it does its work and conversions, the time is always off by 4 hours, since for me the UTC to Local conversion is GMT -4.
The ONLY way i have been able to get this to submit the date in UTC time is by adding:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
BUT this also changes the LocalTime object, even though this object was defined and set before the default TimeZone was changed.
So i get it, the Date() object uses the JVM locale, so any time a Date is created, its created in the default timezone, and apparently whenever the default timezone is changed, all of the Date objects (even if they are already created) change to the new default timezone... I know Date objects are just the millis between now and 1970 whatever, but the TimeZone is obviously being taken into account in the Webservice and this is messing up my results...how can i get the dates the way i want?
I receive a Date String like "2018-06-21T13:30:00Z"
I parse it with the pattern "yyyy-MM-dd'T'HH:mm:ssZ"
I am in GMT+2 and the result looks like 2018-06-21T15:30:00.000+02:00
while i expected it to look like this 2018-06-21T13:30:00.000+02:00
Is the offset supposed to be already applied in the HH:mm:ss part of the Result?
Code
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ").parseDateTime("2018-06-21T13:30:00Z")
joda:2.9.7
Yes the date time given is in the local time of +02:00.
From ISO 8601 Wikipedia Time offsets from UTC:
The following times all refer to the same moment: "18:30Z", "22:30+04", "1130−0700", and "15:00−03:30". Nautical time zone letters are not used with the exception of Z. To calculate UTC time one has to subtract the offset from the local time, e.g. for "15:00−03:30" do 15:00 − (−03:30) to get 18:30 UTC.
So for your case: 2018-06-21T15:30:00.000+02:00 means 15:30 - 02:00 so a UTC of 13:30
I am trying to parse date string with timezone using this code for tests:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZZZZZ", Locale.US);
Calendar calendar = Calendar.getInstance();
calendar.setTime(sdf.parse("2017-07-26T06:00-06:00"));
int offset = calendar.getTimeZone().getRawOffset();
I am trying to change timezone from -06 to +09, but offset always contains 10800000.
How to parse date with timezone correctly (I need time and timezone both)?
Note: -06:00 is an offset, not a timezone - those 2 concepts are related, but they are different things (more on that below).
The problem with SimpleDateFormat and Calendar is that they use the system's default timezone, so even though you parse a date with a different offset (like -06:00), the resulting Calendar will have the default timezone (you can check what zone is by calling TimeZone.getDefault()).
That's just one of the many problems and design issues of this old API.
Fortunately, there's a better alternative, if you don't mind adding a dependency to your project (in this case, I think it's totally worth it). In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP to make it work (more on how to use it here).
To work with offsets, you can use the org.threeten.bp.OffsetDateTime class:
// parse the String
OffsetDateTime odt = OffsetDateTime.parse("2017-07-26T06:00-06:00");
This will parse all the fields correctly (date/time and offset). To get the offset value, similar to calendar.getTimeZone().getRawOffset(), you can do:
// get offset in milliseconds
int totalSeconds = odt.getOffset().getTotalSeconds() * 1000;
I had to multiply by 1000 because calendar returns the value in milliseconds, but ZoneOffset returns in seconds.
To convert this to another offset (+09:00), it's straightforward:
// convert to +09:00 offset
OffsetDateTime other = odt.withOffsetSameInstant(ZoneOffset.ofHours(9));
As I said, timezone and offset are different things:
offset is the difference from UTC: -06:00 means "6 hours behind UTC" and +09:00 means "9 hours ahead UTC"
timezone is a set of all the different offsets that a region had, has and will have during its history (and also when those changes occur). The most common cases are Daylight Saving Time shifts, when clocks change 1 hour back or forward in a certain region. All these rules about when to change (and what's the offset before and after the change) are encapsulated by the timezone concept.
So, the code above works fine if you're working with offsets and wants to convert to a different one. But if you want to work with a timezone, you must convert the OffsetDateTime to a ZonedDateTime:
// convert to a timezone
ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("Asia/Tokyo"));
// get the offset
totalSeconds = zdt.getOffset().getTotalSeconds() * 1000;
The getOffset() method above will check the history of the specified timezone and get the offset that was active in that corresponding instant (so, if you take a date during DST, for example, the offset (and also date and time) will be adjusted accordingly).
The API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.
You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
You can also use the system's default timezone with ZoneId.systemDefault(), but this can be changed without notice, even at runtime, so it's better to explicity use a specific one.
So time formatting and adjusting has always been my biggest nemesis in programing and I'm having some issues in Android/Java that I can't figure out. I get a timestamp from a server that is formatted in UTC (here's an example 2016-06-17T18:30:00-07:00. Now this time needs to get formatted to the users local time (so for a user in PST it should show as 11:30AM) but so far whatever I try I either get 1AM or 6:30PM (so I know I'm doing something wrong I just don't know what). Here's what I've been trying to do
public static DateTime convertISOStringToDate(String inputString) {
//setup the ISO Date Formatter with GMT/UTC format
DateTimeFormatter formatter = ISODateTimeFormat.dateTimeParser()
.withLocale(Locale.US)
.withZone(DateTimeZone.forOffsetHours(0));
DateTime dateTime = formatter.parseDateTime(inputString);
//now convert the datetime object to a local date time object
DateTimeFormatter localFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.getDefault());
String localString = localFormatter.print(dateTime);
DateTime localDateTime = localFormatter.parseDateTime(localString);
return localDateTime;
So at this point I'm getting 1:30AM, so I know I'm messing it up somewhere in the conversion process but I can't figure it out. I've been trying to google around but so far haven't found much that use the ISODateTimeFormat parser so they don't work either when I try them.
You seem to have a basic mis-understanding of how dates are represented.
A date (in almost every known programming language / library) is represented internally as an offset from a specific 'origin time', known as the 'Epoch'.
In java.util.Date as well as joda dates, the internal representation is the number of milliseconds since midnight, Jan 1, 1980, UTC.
As such, a date does not have a timezone. You only introduce a timezone when you format a date (turn it into a String representation of the date).
You have made the common mistake of parsing a String into a date object, serializing (printing) it back out with a different timezone than the the original string indicated, and then parsing back into a date again, expecting something to have changed. If you do that correctly, you will get back exactly the same date that you started with.
In your case, the "localString" that you get shows the correct time in the local timezone. I'm in EDT, which is UTC-4:00, and I correctly get 2016-06-17 21:30:00 as the result.
As I said, parsing that back into a DateTime, and then looking at it is useless, because:
You'll get the same DateTime back that you started with
Your IDE (or whatever you're using to inspect the DateTime) probably isn't showing what you expect.
You should re-evaluate what you're doing here, and whether you really need to "convert" the DateTime, or to just parse it, and really understand how date formatting works with respect to timezones.
I want to subtract two dates in Android project.
When I use the statement:
DateTime now = new DateTime(DateTimeZone.UTC);
It gives 2014-03-17T12:49:06.670Z value instead of 2014-03-17T14:49:06.670Z (this is my current time on Android device)
When I convert this DateTime (2014-03-17T12:30:08.673+02:00) to UTC Time (2014-03-17T10:30:08.673Z) it gives the correct result but not for DateTime now = new DateTime(DateTimeZone.UTC);
What is wrong with new DateTime(DateTimeZone.UTC);?
Any help would be appreciated.
Try getting your local time this way:
DateTime now = new DateTime();
This time is "your current time on Android device". More precisely DateTime calculates its fields with respect to a time zone. It means it will return UTC+2 if you are located in Eastern European Countries (Winter Time) or Wester European Countries (Summer time).
On my PC nothing is wrong with new DateTime(DateTimeZone.UTC). The type DateTime internally stores the given time zone (here UTC) and uses it for the output of its method toString(), hence the UTC-string-format and not another alternative format with offset = +02:00.