I have a requirement of getting UTC time , hence in many places iam using below code for calcualting utc time.
System.currentTimeMillis() ;
Iam in IST - (GMT+5:30) , System.currentTimeMillis() - should display UTC time (IST-5:30) , instead it is taking current time (GMT+5:30).
I donot want to use the Apache of joda date and time api. i want to use the Java api itslef. Help me in resolve my issue.
System.currentTimeMillis() just returns a long - that's not in any sort of date format.
If you're actually using:
Date date = new Date(System.currentTimeMillis());
System.out.println(date);
then you're just seeing the result of Date.toString(), which always uses the system default time zone.
Use DateFormat (e.g. SimpleDateFormat) to specify the calendar system (typically Gregorian), time zone and format you want to use. For example:
Date date = ...;
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",
Locale.US);
format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String result = format.format(date);
As an aside, I'd strongly recommend abstracting the idea of "getting the current time" into an interface which you implement in one case using System.currentTimeMillis() (or equivalently, just new Date()) but implement for testing purposes with a value you can set and update at will. Then inject this "clock" interface into anything which needs to access the current date/time. It makes it much easier to test time-based components.
(I'd also strongly recommend using Joda Time or the java.time package from Java 8 if you possibly can. I know you've said you don't want to, but I suspect that's because you haven't spent as much time swearing at java.util.Date and java.util.Calendar as some of us. Both of those alternatives will lead to much cleaner code which is much easier to read and reason about. If you're trying to avoid a one-time hit of getting Joda Time into your build process, weigh that against the amount of time you're likely to spend maintaining your code. Or just update to Java 8... Java 7 will be out of free-update support soon anyway...)
Related
I'm scraping some data for a user, part of it is a date in a Unix Timestamp:
The user is living in London and wants to see the date for his specific time zone. As you can see, on GMT it is 6/21, on my time zone (Israel Time Zone) it's 6/22.
I used this snippet code to fix:
private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
txnDate = "1529618400000" //this is hardcoded, just for the example
txnDateValue = new Date(Long.valueOf(txnDate));
TimeZone london = TimeZone.getTimeZone("Europe/London");
sdf2.setTimeZone(london);
txnDate = sdf2.format(txnDateValue);
So that the date will be converted to the correct time zone (London in his case).
It still doesn't work for him - he claims that he sees the date in one day difference.
What could go wrong here?
What could go wrong here?
The Date obtained and stored in txnDateValue could have been read wrong, with bad time zone or bad format or whatever
The DateFormat built and stored in sdf2 could be badly made or badly used, with bad pattern or concurrent use or whatever.
Bottomline, you should design complete programs to test the input/output on your side and your partner's side, and if that's not enough to help you find the problem, you should show us this complete programs.
Code snippets are useless. We don't have problems, you do. If we use code snippets you provide, we won't have problems with them. You're the one who have problems with them. So, there is no sense showing anything but a complete program we can run as-is.
Modern version: use java.time
Instant txnDateValue = Instant.ofEpochMilli(Long.parseLong(txnDate));
ZoneId london = ZoneId.of("Europe/London");
txnDate = txnDateValue.atZone(london).format(DateTimeFormatter.ISO_LOCAL_DATE);
The above gives an Instant of 2018-06-21T22:00:00Z (where Z means UTC) and a txnDate of 2018-06-21. Like you own code it is not thread-safe if some other thread may manipulate txnDate or some other variable involved.
What went wrong in your code?
I cannot tell. Kumesana suggested a race condition, like concurrent use of your SimpleDateFormat, this is a possibility. Other possibilities are that your program isn’t working on the data you think or your user in London made a mistake. Apart from these conditions I believe that your program should produce 2018-06-21.
Link
Oracle tutorial: Date Time explaining how to use java.time including the classes Instant, ZoneId and DateTimeFormatter that I used in my code.
I am saving time with other data to show in my app . I am storing the time in utc in db . Now when i run the program locally it works fine but when i run code on server the time is different from utc . My code to get utc timestamp is
private Timestamp getUTCTimestamp() throws ParseException
{
SimpleDateFormat sdf = new SimpleDateFormat(DATEFORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String utcTime = sdf.format(new Date());
SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
Timestamp dateToReturn = new Timestamp(((Date)dateFormat.parse(utcTime)).getTime());
return dateToReturn;
}
It returns acurate utc time but when i run it on server it doesn't give the utc time e.g i ran the program locally and it gave me "2016-04-17 20:58:55" which was right and then after 10 mins i ran the code on server and it saved the time "2016-04-17 16:02:46" which was different .My server location is in netharlands. I don't understand , shouldn't the utc time be same everywhere??
Why are you formatting and then parsing the formatted string? Just use:
private Timestamp getUTCTimestamp() throws ParseException
{
return new Timestamp(new Date().getTime());
}
As to the issue you're seeing, I think #Stanislav Palatnik's comment is correct. You need to set the timezone on your format that is parsing the time string. Or just use the same format for formatting and parsing.. but again, why do you even need to go through that work?
If you are going to save current time on DB, it is much better to save with NOW() function of MySQL to make sure wherever the code runs, as far as the DB is the same, NOW() values will be consistent and you don't need to create time objects and lines of code to handle current time on java side.
see: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_now
You are using old troublesome classes that are now outmoded. Avoid using SimpleDateFormat, java.util.Date/.Calendar and such, and minimize use of java.sql types.
Among their many problems is the behavior of toString method, applying a default time zone while generating the string. This confuses debugging efforts.
java.time
The java.time classes supplant the old date-time classes. Built into Java 8 and later, available as back-ports to Java 6 & 7 and to Android.
Do your business logic in java.time. Use java.sql only until JDBC drivers are updated to handle java.time types directly.
Define your column as something close to the SQL standard TIMESTAMP WITH TIME ZONE. Not "WITHOUT".
An Instant is a moment on the timeline in UTC.
Instant instant = Instant.now();
Convert to java.sql.Timestamp for storage in database.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
Going the direction.
Instant instant = ts.toInstant();
The toString methods in java.time classes do not apply mysterious time zones when generating the textual representation of their date-time value. And they use standard ISO 8601 formats to further clarity.
So we go in and out of the database
all in UTC, no time zones, very simple, very clear.
When you need a wall-clock value such as far presentation to user, Apple a time zone to the instant to get a ZonedDateTime. Covered in detail in many other pages in Stack Overflow.
Your servers should be assigned a time zone of UTC (or Iceland). But never depend on that. Using the approach shown above makes the server’s time zone irrelevant.
No answer could have helped me because i found the reason and it had nothing to do with the code . I ran this command Date -u on putty and realized that the time isn't synchronized with utc and i don't know why . This post helped me in getting to this reason. I haven't tried the solution so if someone has a better solution feel free to tell me :) This is the
link
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.
Is their any function or other way to check if 24H has passed since some time variable, using java?
**I need this code to support android
System.getCurrentTimeMillis() gives you the current time in milliseconds. Check if its value is more than 24 hours greater than the stored value.
I already used a library called joda-time. This library is very usefull when comes the time to manipulate dates, times, intervals, etc. It require some investisment to learn how to use the library, but once its done the code is more expressive.
For example you can calculate interval of time like this:
Days days = Days.daysBetween(start, end);
Hours hours = Hours.hoursBetween(start, end);
You can convert jdk Date to Joda DateTime an vice versa using this code:
// from Joda to JDK
DateTime dt = new DateTime();
Date jdkDate = dt.toDate();
// from JDK to Joda
dt = new DateTime(jdkDate);
It might be overkill for your needs, but I tought it could be good to know that such library exists.
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.