I am using Android's Calendar object and I am using the getTimeInMillis() method, but when I look at the Value it gives me it is a really long number. I am trying to replicate this format but I don't know how as when I take the current time in 24 hour mode and convert it to milliseconds I am completely off.
Example:
Calendar.getTimeInMillis() : at 11:46 pm = 1,349,585,220,205
Time at 11:46 pm using formula[(23 * 60 * 60 * 1000) + (46 * 60 * 1000)] = 85,560,000
I'm wondering if there is some kind of formula the calendar is using to convert the current time to Milliseconds and how I can replicate this.
Thank you!
It's the number of milliseconds since the epoch, 1/1/1970. See this article on Unix time.
1,349,585,220,205 milliseconds / (1000 * 3600) = number of hours = 374884.7833902778
374884.7833902778 hours / 24 = 15620.19930792824 days
15620.19930792824 days / 365 days = 42.79506659706368 years
1970 + 42 years = 2012
(This is not precise due to not taking into account daylight savings time. Use a real datetime library!)
Related
Instant i1 = Instant.now();
Instant i2 = Instant.now().plusSeconds(60 * 60 * 24 * 365);
Duration<IsoUnit> dur = Duration.from((TemporalAmount) java.time.Duration.between(i1, i2));
System.out.println(dur);
this code prints P365D, is there a way to make units fill up the next bigger unit, so this becomes P1Y and if i had like P334D to P11M and so on?
time4j version is 4.38
The other comments and answers are completely right to say that a year is not always equal to 365 days.
The Time4J-method net.time4j.Duration.from(TemporalAmount) returns a normalized duration using STD_PERIOD as normalizer. The documentation of this normalizer says:
Normalizes the duration items on the base of 1 year = 12 months and 1
day = 24 hours and 1 hour = 60 minutes and 1 minute = 60 seconds -
without converting days to months.
So you can only expect the result to be in days when you start with a temporal amount defined in seconds.
If you still want a year then I suggest you to first convert your instants to calendar dates using an appropriate time zone. But in leap years, your code would still produce 365 days and not a year after having added 60 * 60 * 24 * 365 seconds to the second instant. So your addition of seconds is also flawed because it is based on false assumptions.
Side note:
If you want the reverse way, namely how many seconds are in a year then you might use code like
Moment m1 = Moment.nowInSystemTime();
Moment m2 = m1.toZonalTimestamp(ZonalOffset.UTC).plus(1, CalendarUnit.YEARS).atUTC();
long seconds = SI.SECONDS.between(m1, m2); // = 366 days in seconds if applied on date 2019-05-22!
With a future version of Time4J and possible leap second at the end of year 2019, the code might even produce an extra second.
Anyway, I advise you to update Time4J to v5.4 and consider following mappings:
java.time.Instant as input => net.time4j.MachineTime.from(...)
java.time.LocalDateTime/net.time4j.PlainTimestamp => net.time4j.Duration.from(...)
So if you really want years as possible output in printing durations and you have instants/moments then first convert to LocalDateTime/PlainTimestamp (using a time zone or offset) before you create the appropriate duration object.
Update from 2019-05-25:
Another way with the version v5.4 (or later) is possible via "fuzzy" durations. You could normalize the durations you get by applying an approximation. Example:
Duration<IsoUnit> d = Duration.of(60 * 60 * 24 * 365, ClockUnit.SECONDS);
d = d.with(Duration.approximateMaxUnitOnly());
System.out.println(d); // P1Y
Due to the nature of this kind of normalization, you cannot expect exact results.
A year doesn't have a fixed amount of seconds:
Leap years have an additional day on February 29
Leap seconds are sometimes added
Due to above you have to know how many seconds are in a year. It seems like instead of Instant and Duration you should be using LocalDate and Period (at least when using java.time):
LocalDate d1 = LocalDate.now();
LocalDate d2 = d1.plusYears(1);
Period p = Period.between(d1, d2);
System.out.println(p); // P1Y
Is there a way to get the current time of the day in seconds? Notice I am asking the time of the day, not UTC time.
What I want is a value (in seconds) between the range 0 - 86,400 (12:00AM - 11:59PM). I'm working on an app that works on a daily basis, and when the day ends, the time (in seconds) should restart back at 0 again.
So let's say it's 10:00AM. I should be getting 36,000 seconds, and if my time is 5:00PM, I should be getting 61,200 seconds.
PS: I do not know the time before hand. The program will figure it out by itself using a currentTime() function.
With Java 8, you could create a Duration instance.
For example :
LocalDateTime date = LocalDateTime.now();
long seconds = Duration.between(date.withSecond(0).withMinute(0).withHour(0), date).getSeconds();
Or more simply you could convert the LocalDateTime to a LocalTime instance and then apply the toSecondOfDay() method :
LocalDateTime date = LocalDateTime.now();
int seconds = date.toLocalTime().toSecondOfDay();
From the java.time.LocalTime javadoc :
public int toSecondOfDay()
Extracts the time as seconds of day, from 0 to 24 * 60 * 60 - 1.
Use a java.time.LocalTime and a java.time.temporal.ChronoField:
// 10:00 AM
LocalTime d = LocalTime.of(10, 0);
System.out.println(d.get(ChronoField.SECOND_OF_DAY)); // 36000
// 05:00 PM
d = LocalTime.of(17, 0);
System.out.println(d.get(ChronoField.SECOND_OF_DAY)); // 61200
// 23:59:59
d = LocalTime.of(23, 59, 59);
System.out.println(d.get(ChronoField.SECOND_OF_DAY)); // 86399
// midnight
d = LocalTime.of(0, 0);
System.out.println(d.get(ChronoField.SECOND_OF_DAY)); // 0
This prints:
36000
61200
86399
0
Notes:
That's just examples. If you want to get the value from the current time, just use LocalTime.now() (or LocalTime.now(ZoneId.of("timezone-name")) as pointed by #Ole V.V.'s answer).
As a timezone-name, always use IANA timezones names (always in the format Continent/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 call d.toSecondOfDay() if you want (it's equivalent, as get(ChronoField) internally calls toSecondOfDay).
I suggest:
int secondsOfDay = LocalTime.now(ZoneId.of("Europe/Rome")).toSecondOfDay();
Points to note:
Use an explicit time zone to remind the reader and yourself that the choice of time zone matters and that you have made a conscious choice. Either ZoneId.systemDefault(), or even better is if it would make sense in your situation to give a named zone like for example ZoneId.of("Europe/Rome").
The snippet converts 10:00 AM to 36,000 no matter when the day began; because of summer time and other anomalies it may not have begun at 0:00 midnight, and there may be a gap or overlap early in the morning. To get the true number of seconds since the day began, you will need some calculation involving LocalDate.now(yourTimeZone).atStartOfDay(yourTimeZone).
You can just convert the seconds minutes hour fields into seconds and add them up
Calendar c = new GregorianCalendar();
int totalSecs = c.get(Calendar.SECOND) + 60 * c.get(Calendar.MINUTE) + 3600 * c.get(Calendar.HOUR_OF_DAY);
You could use the SimpleDateFormat to extract the hours minutes and seconds. It works on Java 7 and Java 6 and Java 8, and it adapts to your local time and timezone:
String timeNowHMS[] = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH)
.format(System.currentTimeMillis())
.split(":");
int secondsPassedInTheDay =
Integer.parseInt(timeNowHMS[0]) * 60 * 60
+ Integer.parseInt(timeNowHMS[1]) * 60
+ Integer.parseInt(timeNowHMS[2]);
I am trying to get the difference between the current time and the time which is stored in DB.
I tried below code but its not giving the correct result since java.lang.System.currentTimeMillis() returns
UTC time whereas we save date to our application in EST format.
Code :
java.lang.System.currentTimeMillis() - emp.getModifiedDate()
Could you please suggest me a correct way to do it ?It will be very helpful for me
Thanks
System.currentTimeMillis() returns the number of milliseconds since January 1, 1970 UTC. It is time-zone agnostic.
If you are storing the time in the database as millis then simply subtracting the two numbers will give you the correct difference.
If you are storing the time in some other way (e.g. as a String), you can parse it (e.g. with SimpleDateFormat) to take into account the time zone and then obtain a Date from which you can obtain the millis.
Hope this helps! This will give you difference in no of days.
Date date1 = new Date();
long diff = date1.getTime() - emp.getModifiedDate().getTime();
System.out.println((int) (diff) / (1000 * 60 * 60 * 24)));
For more read this
I am working on an application that supports Google 2-step verification. This application also supports a feature to 'trust this device for 30 days'.
I use a database to save all this information such as IP-addresses and expire times. Now when I fill in the timestamp System.currentTimeMillis() + 30 * 24 * 60 * 60 * 1000 to add 30 days to the current time, it inserts a timestamp earlier than the current time into the database.
For example: the current time = 1483223733000 (2016-31-12 11:36 PM UTC+1).
Now when I add 30 days (which is 2592000000 milliseconds, it comes to a date similar to 1481520984841 (2016-12-12 6:36 AM UTC+1) which is not 30 days ahead, but rather about 19 days back in time.
This problem had to do with a 32-bit integer overflow. Since the maximum value for an integer is 2147483647, 30 days in milliseconds would be too large for an integer and would result in an integer like -1702967296 (Which is about -19 days in milliseconds.)
To solve this problem, I use a long instead of an int. So now I do:
System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000;
You already answered the question of why the calculation is wrong, but I want to recommend you a more idiomatic way to working with dates, if you use Java 8.
If you need to add just 30 24-hour-long days (ie. 24 * 30 hours), use:
Instant.now().plus(Duration.ofDays(30)).toEpochMilli();
or
Instant.now().plus(30, ChronoUnit.DAYS).toEpochMilli();
If you need to add exactly 30 days (some days can be 23 or 25 hours long because of daylight saving time etc) according to the current JVM time zone, use:
ZonedDateTime.now(ZoneId.systemDefault()).plusDays(30).toInstant().toEpochMilli();
or (implicitly use JVM timezone)
ZonedDateTime.now().plusDays(30).toInstant().toEpochMilli();
You could use the Calendar to do this:
Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
//cal.add(Calendar.DATE, 30);
cal.setTimeInMillis(System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
This question already has answers here:
Java - Subtract Days from date [duplicate]
(6 answers)
Closed 8 years ago.
I am trying to do something really simple. I am trying to subtract 2 days from the current day. I get the number of hours from the UI. So in this example, I get 48 hours from the UI. I am doing the following and I don't know what i'm doing wrong here. I think the result of this is it only subtracts a few minutes from the time.
long timeInEpoch = (currentMillis()/1000 - (48 * 60 * 60)); //48 comes from UI
public long currentMillis(){
return new Date().getTime();
}
d = new Date(timeInEpoch * 1000);
I also tried
d1 = new Date(timeInEpoch);
Nothing seems to work. What am I doing wrong here?
try
long millis = System.currentTimeMillis() - 2 * 24 * 60 * 60 * 1000;
Date date = new Date(millis);
it definitely works
Use Calendar API like this to subtract 2 days from a Date object:
Calendar c = Calendar.getInstance();
c.setTime(d);
c.add(Calendar.DATE, -2);
d.setTime( c.getTime().getTime() );
long millisec = d.getTime();
Your code is alright , your variable d should be at offset of 48 hours from the current time on your server.
Make sure the server and your clients are running on the same time otherwise request your server admins to fix the time on your deployment machine.
You would also notice this difference if your client is opening a browser in e.g. Japan and your server is running in USA because of the standard time difference.
try this
long diff = Math.abs(d1.getTime() - d2.getTime());
long diffDays = diff / (2*24 * 60 * 60 * 1000);
Avoid the old java.util.Date and .Calendar classes as they are notoriously troublesome.
Use either Joda-Time or the new Java.time package built into Java 8. Search StackOverflow for hundreds of Questions and Answers on this.
Joda-Time offers methods for adding and subtracting hour, days, and more. The math is done in a smart way, handling Daylight Saving Time nonsense and other issues.
Quick example in Joda-Time 2.7 ( as this is really a duplicate Question, see others for more info ).
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zone );
DateTime fortyEightHoursAgo = now.minusHours( 48 );
DateTime twoDaysAgo = now.minusDays( 2 );