Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I want to know the number of hours in a day when the DST (daylight saving time, summer time) is begins and ends.
Am willing to use java.time. Zone ID is Europe/London. The main intention is:
when DST begins in the spring, we will have 23 hours in one day because clocks are turned forward
conversely when DST ends, we will have 25 hours in one day.
I have an epoch value from which I should find the number of hours. How is it possible?
ZoneId zone = ZoneId.of("Europe/London");
long epochMillis = 1_540_700_000_000L;
LocalDate date = Instant.ofEpochMilli(epochMillis)
.atZone(zone)
.toLocalDate();
int hoursInDay = (int) ChronoUnit.HOURS.between(
date.atStartOfDay(zone),
date.plusDays(1).atStartOfDay(zone));
System.out.println(date + " is " + hoursInDay + " hours");
I didn’t choose the milliseconds since the epoch at random. In this case the output is:
2018-10-28 is 25 hours
Transition to standard time will happen on the last Sunday in October, this year on October 28.
The Australia/Lord_Howe time zone uses 30-minute DST transitions, so in that time zone the day would be either 23.5 hours or 24.5 hours, which in the above will be truncated to 23 and 24. But for London you should be OK until those crazy British politicians decide to do someting similar. :-)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I have a date say 2022-07-10 as date (YYY/MM/dd) and time as 00:15
ie. 202207**10*****0015***
after subtracting 30 mins from above the result must be
2022-07-09 and time as 23:45
ie. 202207**09***2345***
other scenarios:
202207100030 -->202207100000
202207100010 -->202207092340
202207100035 -->202207100005
Could you please help me out with this.
What you want doesn't make sense. 2022-07-10 00:15 minus 30 minutes? That's not 2022-07-09 23:45. Not neccessarily, anyway. Maybe a timezone shift means it's 2022-07-10 00:45 (but, before the timezone change). Or it's 2022-07-09 22:45. Or perhaps it's 2022-07-01 23:45 - it's been a good long while but a locale can skip a day (last time: When one of the islands in the pacific decided to hop across the date line), or even half a month (last time: Russian revolution. It's still in the 1900s).
You can't 'do' date-diff math on Local date/time concepts; a time zone is required.
Once you've established one this is trivial:
First, parse whatever you have into a LocalDate, LocalDateTime, OffsetDateTime, Instant, or ZonedDateTime object. These are all fundamentally different concepts - a key part of doing any time-based anything is figuring out what concept you're dealing with. For example, you seem to believe you're dealing with local date/times (no timezone), and yet also with a concept that can 'do' date diff math (which is mutually exclusive, hence, some more analysis of the situation is required).
Then, transform what you have into the date/time concept you need to do the operation.
Do the operation.
Transform some more if needed.
format it back to a string if you want.
If you try to shortcut and skip steps, it'll work, until it doesn't. Because date/time is just that hard.
For example:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMM**dd*****HHmm***");
LocalDateTime ldt = LocalDateTime.parse("202207**10*****0015***", dtf);
This is a good start; you now have an LDT object with the right year, month, day, minute, and hour.
Let's localize it somewhere and do the math:
ZonedDateTime zdt = ldt.atZone(ZoneId.of("Europe/Amsterdam"));
zdt = zdt.minusMinutes(30);
System.out.println(zdt.format(dtf));
Prints 202207**09*****2345***; I assume that's what you want.
You need to use LocalDateTime.minus method:
DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime d = LocalDateTime.parse("2022-07-10 00:10", DATEFORMATTER);
d.atZone(ZoneId.systemDefault());
LocalDateTime d2 = d.minus(Duration.ofMinutes(30));
LocalDateTime d3 = d.minus(30, ChronoUnit.MINUTES);
System.out.println(d2); //2022-07-09T23:40
System.out.println(d3); //2022-07-09T23:40
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
This post was edited and submitted for review 11 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
Code
Date dates = new Date(Long.MAX_VALUE);
output -
292278994-08-17 12:42:55
I want to get the largest date today onwards. How to get this using another way.292278994 this year cant save my DB I need only 4 characters for the year.
To get the boundary dates of the current year, you can use the java.time API and set the month/day values to january 1st and december 31st respectively:
LocalDateTime now = LocalDateTime.now();
LocalDateTime startOfYear = now.withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime endOfYear = now.withMonth(12).withDayOfMonth(31).withHour(23).withMinute(59).withSecond(59).withNano(999999999);
System.out.println(startOfYear);
System.out.println(endOfYear);
Output:
2022-01-01T00:00
2022-12-31T23:59:59.999999999
Epoch milliseconds are milliseconds counted from the very first moment of 1970 and they are stored as long in Java. That means Long.MAX_VALUE will get you the moment in time that is as far in the future as this representation allows. A moment that is beyond some maximum date of the current year, like some hundred million years beyond…
If you are on Java 8 or higher and try to use an Instant with Long.MAX_VALUE like this:
public static void main(String[] args) {
// use the greates Long as epoch millis and create an Instant from it
Instant instant = Instant.ofEpochMilli(Long.MAX_VALUE);
// represent the Instant as date and time of day in a specific zone
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
// define the output format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
// and print the
System.out.println(zdt.format(dtf));
}
You will get the following output:
+292278994-08-17 07:12:55
You may want to adjust the ZoneId to the desired one and remove the leading plus from the output…
But basically understand that epoch milliseconds are not years.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
From the java.time library, I am using the static method Duration.between to calculate the time in seconds between two LocalDateTime.
Everything works as expected, except for the case below, where I should see a difference of 60 seconds, instead of 1500.
Here is the code to reproduce the error:
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;
class Scratch {
public static void main(String[] args) {
LocalDateTime endDate = LocalDateTime.now().with(DayOfWeek.SATURDAY).withHour(0).withMinute(0);
LocalDateTime startDate = LocalDateTime.now().with(DayOfWeek.SUNDAY).withHour(1).withMinute(0);
System.out.println(Duration.between(endDate,startDate).toMinutes());
}
}
I am sure I am missing something here.
There are 25 hours or 1500 minutes between Saturday 00:00 and Sunday 01:00
Maybe do you want Sunday 00:00 and Sunday 01:00?
You are calculating the duration between Saturday morning at midnight (00:00) (or Friday evening at midnight, whichever way you prefer) and Sunday morning at 01:00.
The difference is 25 hours, or 1500 minutes. The result looks fine.
I'm trying to convert a no of months into milliseconds
For example:
6 months = X milliseconds
There's no fixed answer to that, because it depends on which months those are - and indeed which year it is. Also potentially which time zone you're in, if you want to take account of that. (I'm assuming you mean the Gregorian calendar, by the way - different calendar systems have different month lengths.)
You could get some sort of "reasonable approximation" by assuming 365.25 days in a year, and saying that 6 months is half of that, then find out that many days in milliseconds. But it would only be an approximation.
For "how many milliseconds does it take to get from date/time X to 6 months later" you'd use an API (even Calendar would work for this particular case, although I'd recommend Joda Time or java.time in Java 8):
Set your start date/time, in the appropriate calendar and time zone
Fetch the "milliseconds since the Unix epoch" (which is easy enough to retrieve in any API) and remember it
Add 6 months
Fetch the "milliseconds since the Unix epoch" again, and subtract the earlier value from it
If you know exactly from when to when those 6 months reach, you can use a variety of ways to calculate the duration, using java.util.Calendar, JodaTime, or the JDK1.8 time API.
But if you don't have particular dates in mind, you can take an average duration for your month.
No API in the world can change that fact.
For example, the JDK1.8 time API uses this for the duration of a month in seconds: (from java.time.temporal.ChronoUnit)
MONTHS("Months", Duration.ofSeconds(31556952L / 12)),
31,556,952 is the number of a seconds in a year, based on a year that lasts 365.2425 days.
You can use the same number directly and get the same result as with the time API:
long months = 6;
long seconds = months * 31556952L / 12;
long milliseconds = seconds * 1000;
Result:
15,778,476,000
Calendar today = Calendar.getInstance();
Calendar sixMonthsAhead = Calendar.getInstance();
sixMonthsAhead.add(Calendar.MONTH, 6);
long differenceInMilis = sixMonthsAhead.getTimeInMillis() - today.getTimeInMillis();
You could also use...
sixMonthsAhead.add(Calendar.DATE, 180);
// or 183 days because 365 / 2 is approximately 183.
instead of...
sixMonthsAhead.add(Calendar.MONTH, 6);
for a more accurate result. But like Jon has mentioned, it will always vary depending on what day of the year it is.
The answer by Jon Skeet is correct.
Joda-Time
Assuming you could specify a pair of beginning and ending points on a time line, here is some example code using the Joda-Time 2.3 library.
This code grabs the current moment, adjusts to first of the month, and adjusts to first moment of that day. Then it adds 6 months. Joda-Time is smart about adding the months, taking into account leap year and various lengths of months. This span of 6 months is then represented as an Interval instance. From that we calculate the number of milliseconds. Note that count of milliseconds needs to be a long (64-bit) rather than an int (32-bit) we Java programmers more commonly use. Lastly, for fun, we see what this span of time looks like when formatted in the ISO 8601 standard’s "Duration" format.
DateTimeZone dateTimeZone = DateTimeZone.forID( "Europe/Paris" ); // Better to specify a time zone than rely on JVM’s default.
DateTime start = new DateTime( dateTimeZone ).withDayOfMonth( 1 ).withTimeAtStartOfDay();
DateTime stop = start.plusMonths( 6 );
Interval interval = new Interval( start, stop );
long milliseconds = interval.toDurationMillis(); // A long, not an int.
Period period = interval.toPeriod(); // For fun… ISO 8601 standard's Duration format.
Dump to console…
System.out.println("start: " + start );
System.out.println("stop: " + stop );
System.out.println("interval: " + interval );
System.out.println("milliseconds: " + milliseconds );
System.out.println("period: " + period );
When run…
start: 2014-04-01T00:00:00.000+02:00
stop: 2014-10-01T00:00:00.000+02:00
interval: 2014-04-01T00:00:00.000+02:00/2014-10-01T00:00:00.000+02:00
milliseconds: 15811200000
period: P6M
I am trying out my hand in finding out records which have been updated in the Oracle 11g DB in last 24 hours or 7 days or 30 days. I am able to get the desired functionality using "java.util.Calendar"
Date today = new Date();
Calendar cal = new GregorianCalendar();
cal.setTime(today);
//For last 7 days
cal.add(Calendar.DAY_OF_MONTH, -7);
however I am wondering if anyone has done this with Joda-Time API?
You need to define exactly what you mean by "last 24 hours" and "last 7 days". Do you really mean the last 24 hours, or "since the same local time yesterday"? The latter could mean 23 hours or 25 hours, due to daylight saving transitions.
If you really, really want exactly 24 hours and exactly 7 * 24 hours, I would use Instant:
Instant now = new Instant();
Instant nowMinus24Hours = now.plus(Durations.standardHours(-24));
Instant nowMinus7Days = now.plus(Durations.standardDays(-7));
Note that Instant has no concept of a time zone or calendar - it's just a point on the timeline; it's an appropriate data type to use for timestamps and the like.