I would like to start by saying that I've read several threads similar to this one, but none of them really solved my problem.
I would also like to state that I've tried to use SimpleDateFormat and joda.DateTime without any success.
The problem is the following:
I have a Calendar object that holds the information about a specific date: 2008-04-30T00:00:00Z
When using the calendar.getTime() method I can get different results because I know that that method is looking for the local value
Thus:
UK: 2008-04-30T01:00:00.000+0100
US: 2008-04-30T20:00:00.000-0400
But I would like to get a Date object that holds just the Date and Time values "2008-04-30T00:00:00" ignoring completely any timezone.
How can I do that?
As I mentioned before I tried to use
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
but I always end up with the same results.
Any help would be really appreciated
Cheers.
Found out that you can clear the Timezone by using code below:
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.ZONE_OFFSET);
Calendars and Dates mean nothing without a TimeZone.
Calendars and dates cannot exist without a timezone.
You can't ignore completely any timezone.
You can create a Calendar for Greenwich Mean Time (offset zero) like this:
TimeZone zone = TimeZone.getTimeZone("Etc/GMT");
Calendar cal = Calendar.getInstance(zone);
This represents a Date/Calendar that is only meaningful in the GMT timezone.
It sounds like you want a timestamp, which represents an instant in time.
As others have pointed out, Calendar and Date objects cannot exist without a time zone.
I believe you may want to use the LocalDateTime class introduced in Java 8 with the new time API:
LocalDateTime literal = LocalDateTime.of(2008, 4, 30, 0, 0, 0);
LocalDateTime parsed = LocalDateTime.parse("2008-04-30T00:00:00"); // ISO-8601 by default
Assert.assertEquals(literal, parsed);
Do you use a standard constructor for initializing Calendar? What if you used the constructor which allows to specify the time zone and locale?
protected Calendar(TimeZone zone, Locale aLocale)
Old, but still incorrect.
"When using the calendar.getTime() method I can get different results because I know that that method is looking for the local value"
That is a misconception. getTime() will get the Milliseconds only. Countet as GMT.
ONLY during formatting of the Output the time zone becomes relevant. Sind the original poster did not show the code, it can not be decided, where the error occurs.
Related
I'm using ibm's MessageFormat library to localize an incoming date.
The task here is to run a few checks on the date before showing it to the end user. I get a ZonedDateTime object and I need to make sure that it doesn't fall in the weekend, which I do using the getDayOfWeek.
My problem happens when I try to convert my date to a string using MessageFormat. Since MessageFormat accepts only java.util.Date objects, I convert my ZonedDateTime -> Instant -> Date. Unfortunately, this method results in my "Monday" becoming a "Sunday," as shown below.
I noticed that this "loss" happens upon the Date conversion. This is because the Date.toString() object is being invoked by MessageFormat, and the former uses the JVM's default timezone (in my case, PST). As a result, my UTC gets implicitly converted to a PST and I lose a day.
Any ideas how to tackle this? Is there anything else that I can pass to MessageFormat? Is there a way to use Date but not get this undesired behavior? Is there another localization library I can use?
Internally, MessageFormat uses a DateFormat object but does not allow you to set its timezone. #Assylias linked a question where the answer tries to pull out the internal DateFormat, set its timezone, and then use the MessageFormat as usual, which resolves the issue.
However, I found that to be too wordy, particularly because you have to create a new MessageFormat everytime (as opposed to reusing the MessageFormat that you already set the timezone for).
What I opted for was to simply use SimpleDateFormat directly.
// I have a ZonedDateTime zonedDateTime that I want to print out.
final SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MM dd", locale);
dateFormat.setTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone()));
final String formattedDateString = dateFormat.format(Date.from(zonedDateTime.toInstant()));
I then use String.format to insert my formatted date into a larger string. Hope this helps.
This question already has answers here:
Unix epoch time to Java Date object
(7 answers)
Convert timestamp in milliseconds to string formatted time in Java
(10 answers)
Closed 5 years ago.
How to change milliseconds to Date object in yyyy-MM-dd HH:mm:ss format like 2017-04-12 23:14:52?
You cannot do that. For a couple of reasons.
TL;DR: Don’t use Date, use Instant. Neither of these can have a format in them. Formatting into a string is dependent on time zone, so you need to choose a time zone.
First, I understand from the discussion that you are asking for a java.util.Date object having the format yyyy-MM-dd HH:mm:ss. A Date object does not have and cannot have a format in it. The thing you should try to understand here is the difference between data itself and presentation of data to a user. An int may hold the value 25389, but it doesn’t hold it in the format 25389 (in fact the internal representation is quite different from 25389). The same int may be presented to a user as 25389, 000025389, 25,389 or +25389, just to mention a few out of many possibilities. The formatting happens outside the int while the int stays just the same.
Similarly, a Date object holds a point in time. The same date may be formatted into for example 2017-04-12 23:14:52 or April 12, 2017 11:14:52 PM. It may even be formatted for different time zones, which would be a good idea if the system has users in different time zones. Alternatively we may show the user a calendar leaf and/or a clock showing the time. Again, formatting happens outside of the Date while the Date stays just the same.
Elaborating on the time zone issue, the same point in time represented by the same millisecond value could be formatted to 2017-04-12 17:44:52 in UTC, 2017-04-12 19:44:52 in my time zone, 2017-04-12 23:14:52 in Asia/Kolkata time zone or even 2017-04-13 05:44:52 in Pacific/Auckland time zone. Note that in the last case not even the date is the same. So there is not just one way to change your milliseconds into the format you asked for. We need to know which time zone you want it for before we can help you.
So what I believe you need is not one thing, but two
A way to store your point in time in your program.
A way to format your point in time into a string in yyyy-MM-dd HH:mm:ss format for a user in some time zone.
For storing your point in time, use either of
A long for the milliseconds value you already have
A java.time.Instant object.
Why didn’t I mention java.util.Date? Because this class is long outdated. Its design turned out to be troublesome very quickly. They tried to repair it by deprecating most of the methods and introducing java.util.Calendar, but that didn’t work very well either. Finally, drawing on the experiences from a library known as Joda-Time they introduced the java.time classes in Java 8 in 2014. That’s three years ago as of writing, and counting. So IMHO we should by now have thrown Date and friends overboard and started using the newer classes. So prefer Instant over Date.
Changing your milliseconds to an Instant is straightforward:
long milliseconds = 1492019092000L;
Instant pointInTime = Instant.ofEpochMilli(milliseconds);
For formatting your instant into a string for the user, as I said, we require a time zone. Then do
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String formattedDateTimeString = pointInTime.atZone(ZoneId.of("Asia/Kolkata"))
.format(formatter);
So you need to fill in the desired time zone where I put ZoneId.of("Asia/Kolkata"). If you want to use the JVM’s current time zone setting, just fill in ZoneId.systemDefault(). Beware, though, that the time zone setting may be changed, even by an unrelated program running in the same JVM, so relying on this may be fragile.
The result of the above code snippet is a string like
2017-04-12 23:14:52
PS If after reading the above you really insist, here’s how to get a java.util.Date from the above:
Date myOutdatedDateInstance = Date.from(pointInTime);
(and excuse me for repeating, it still doesn’t have the desired format, that is not possible).
You can try this sample code.
public class MillDateConverter {
public static String dFormat = "yyy-MM-dd HH:mm:ss";
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dFormat);
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
long milliSec=Long.parseLong("1086073200000");
System.out.println(milliSec);
calendar.setTimeInMillis(milliSec);
System.out.println(simpleDateFormat.format(calendar.getTime()));
}
}
I have a timezone-delicate report in Jasper and I can't really seem to figure out how to show a few dates relative to a timezone.
I have a view which returns dates with the following format:
"2015-03-02 11:45:00+01"
"2015-03-02 23:59:59+01"
"2015-03-03 00:00:00+01"
"2015-03-03 08:00:00+01"
"2015-03-03 09:20:00+01"
"2015-03-03 11:00:00+01"
"2015-03-03 09:00:00+01"
"2015-03-03 09:30:00+01"
etc (notice the +01 at the end)
In my report, I have:
new SimpleDateFormat("HH:mm", $P{REPORT_LOCALE}).format($F{start_date});
However, for example, for "2015-03-02 11:45:00+01" I don't get 12:45 shown, I get 11:45.
Also, I need to sum-up the hours (they're intervals) and this gives me a 1hr (in this case) error.
Can anyone help me show the correct hour?
Thanks!
SimpleDateFormat takes a Date, not a Calendar - which means it can't be provided the time zone in the value itself.
Assuming you need to stick with SimpleDateFormat (rather than using Joda Time or Java 8's java.time, for example) then you'll need to set the time zone on the SimpleDateFormat itself. If you need to take the time zone from the data (rather than having a report-wide zone) then you'll need to call setTimeZone before formatting each value - but of course, you'll also need to make sure you've got the time zone in the value, and java.sql.Timestamp doesn't have any notion of a time zone, as far as I'm aware.
I'm trying to call a .Net webservice from Java. I have a java.sql.Date that I am converting to a Calendar which then gets passed through to .Net as a DateTime.
Unfortunately, when it gets to the other side it is a day behind the date that was sent. This is a known issue as per (http://wiki.apache.org/ws/FrontPage/Axis/DotNetInterop) and I'm sure there is a way around it but I just can't seem to find it.
Does anyone know of a way to correctly convert a java.sql.Date to a Calendar so that there is no 24 hour offset issue?
The code I have at the moment is as follows:
java.sql.Date myDate = Date.valueOf("2011-04-11");
Calendar calendarDate = Calendar.getInstance();
calendarDate.clear();
calendarDate.setTime(myDate); //we then pass calendarDate off to webservice...
When I look at the timezone info I see the following:
In Java the following gets me "Eastern Standard Time (New South Wales)":
calendarDate.getTimeZone().getDisplayName();
In .Net the following gets me "AUS Eastern Standard Time":
TimeZone.CurrentTimeZone.StandardName;
As far as I am currently aware, both Java and .Net have the local time in the same timezone...
I'm not sure if this is the correct thing to do...but it seems to have fixed my problem...
java.sql.Date myDate = Date.valueOf("2011-04-11");
Calendar calendarDate = Calendar.getInstance();
//normalise the SQL date
//http://download.oracle.com/javase/6/docs/api/java/sql/Date.html
calendarDate.set(Calendar.HOUR_OF_DAY, 0);
calendarDate.set(Calendar.MINUTE, 0);
calendarDate.set(Calendar.SECOND, 0);
calendarDate.set(Calendar.MILLISECOND, 0);
calendarDate.setTime(myDate);
calendarDate.set(Calendar.DST_OFFSET, 0); //Clear the daylight savings offset
calendarDate.set(Calendar.ZONE_OFFSET, 0); //Clear the timezone offset
Setting the offset to zero seems to allow it to avoid the offset issue altogether.
I think this works because the Java and .Net webservices seem to interact like this:
Java dates are GMT plus an offset
Axis seems to pass the date to .Net without the offset information.
.Net then assumes local time for a time that is actually GMT...which leads to offset problems of +/-24 hours.
I think my fix of setting the offset to zero after setting the date causes the Calendar to keep the date consistent with local time in the absence of the offset. Thus when the date gets to the .Net webservice the assumption of local time is correct.
I have no idea if that is the case or not and would appreciate a better explanation...but for now, unless told otherwise, this solution appears to work...
according to that article, .net always handles dates in the local timezone (wow, is that broken). so, you must determine the timezone of the .net service and set that timezone on your Calendar instance.
I know there are other similar questions to this, but I came up with my own way of getting the current time in a specific time zone, so I just wanted to confirm if it is correct or not, or there are gotchas I didn't take care of.
Calendar cal = Calendar.getInstance();
// Assuming we want to get the current time in GMT.
TimeZone tz = TimeZone.getTimeZone("GMT");
cal.setTimeInMillis(calendar.getTimeInMillis()
+ tz.getOffset(calendar.getTimeInMillis())
- TimeZone.getDefault().getOffset(calendar.getTimeInMillis()));
// Calendar should now be in GMT.
Is the above correct at all? I did my own test and it seemed to be working as expected, but just wanted to confirm it again with the experts in Stack Overflow.
If you simply do a Calendar.getInstance with the TimeZone argument, the calendar's internal state for the get() methods will return you the field with the time for that timezone. For example:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// if i run this at 9 EST this will print 2
System.out.println(cal.get(Calendar.HOUR));
If you just need the local time for display purposes, you can set the TimeZone on your format object. For example:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(new Date()));
Like Macarse said though, Joda time is where it's at if you need to do anything more complex. The Java date APIs are a nightmare.
I'd prefer using joda-time instead of that.
Check this link.