I'm using the library DateTime to store date values for birthdays.
DateTime dateTime01Abegin = new DateTime(2013, 5, 23, 00, 00);
DateTime dateTime01Bbegin = new DateTime(2012, 5, 22, 00, 00);
Running the method .getDayOfYear() on them, I am getting a value of 143 for both. But one is May 23rd and one is May 22nd - I can't figure why they're returning the same value!
2012 has 366 (february 29) days and 2013 has 365, that's why both dates return 143.
The count of the days in a year has an offset of one day in leap years, since after february 28 leap years have an additional day compared to normal ones.
Not every year is 365 days long, some years are 366 days long.
2012 is a leap year, which means that it has an additional day, February 29th. For dates prior to February 28th, the .getDayOfYear() will return the same values for similar dates for any year. For dates after February 28th, .getDayOfYear() will return the same values for similar dates if both of those dates are in a leap year, or if both of those dates are not in a leap year. Otherwise, they should be off by one.
Leapyears. 2012 is a leapyear, so there was a Feb 29th, pushing all the "later" dates up one slot, so your May 22nd is actually day 143 in both years.
2012 was a leap year. So may 23 2013 came 1 day before may 23 2012.
Related
I'm having trouble finding a post where the solution is something else besides
Get day difference and divide by 7
I'm looking to get the difference in calendar weeks between two dates, where the weeks start on Mondays.
For instance, the number of weeks between Nov 4th, 2019 and Nov 10th, 2019 should be 0.
However, the number of weeks between Nov 10th, 2019 and Nov 11th, 2019 should be 1.
The solution should also account for dates in different years. Any solutions that use LocalDate?
ChronoUnits have a between method which returns the number of complete units between a start and end date/time. To count weeks Monday to Sunday, you could "round down" your dates to the previous Monday. In your case it could look like this:
LocalDate start = LocalDate.of(2019, 11, 10);
LocalDate end = LocalDate.of(2019, 11, 11);
LocalDate mondayStart = start.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate mondayEnd = end.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
System.out.println(ChronoUnit.WEEKS.between(mondayStart, mondayEnd));
I would start with a known Monday and calculate the week number counting from then.
1st Jan 1962 was a Monday (other Mondays are available).
LocalDate knownMonday = LocalDate.of(1962,1,1);
LocalDate start = LocalDate.of(2019, 11, 10);
LocalDate end = LocalDate.of(2019, 11, 11);
long sWeek = (long)Math.floor(knownMonday.until(start,ChronoUnit.DAYS)/7.0);
long lWeek = (long)Math.floor(knownMonday.until(end ,ChronoUnit.DAYS)/7.0);
System.out.println(lWeek-sWeek);
Use GregorianCalendar . It has methods for computing differences in terms of weeks.
I'm parsing a date, "00:45:00 Mar:2017", "01:45:00 Mar:2017" and "02:45:00 Mar:2017".
All of the others give the correct output, besides "01:45:00 Mar:2017", which always rounds to "02:45:00 Mar:2017".
Code
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:dd MMM:yyyy");
Date date = simpleDateFormat.parse("01:45:26 Mar:2017");
System.out.print(date);
} catch (ParseException e) {
System.out.print(e.getMessage());
}
Output from "00:45:26 Mar:2017"
Sun Mar 26 00:45:00 GMT 2017
Output from "01:45:26 Mar:2017"
Sun Mar 26 02:45:00 BST 2017
Output from "02:45:26 Mar:2017"
Sun Mar 26 02:45:00 BST 2017
Day zero?
Your pattern says the third pair of digits is day-of-month (dd) but there cannot be a day number zero as seen in your examples with 00.
I suspect that third pair of digits is actually seconds rather than day-of-month, and that your day-of-month is missing.
UK DST Cutover
Yes indeed, in the UK the Daylight Saving Time (DST) cutover “Spring forward” is 2017-03-29 at 01:00. Described here:
Mar 26, 2017 - Daylight Saving Time Started
When local standard time was about to reach
Sunday, March 26, 2017, 1:00:00 am clocks were turned forward 1 hour to
Sunday, March 26, 2017, 2:00:00 am local daylight time instead
Formatting patterns are case-sensitive
Another problem: You used lowercase hh where you probably should be using uppercase HH for 24-hour clock.
Avoid legacy date-time classes
Also, you are using troublesome old date-time classes that are now legacy. Supplanted by the java.time classes.
Apparently the British clocks change on the 26th of March, at 1:00.
If I try to set java.sql.Date as
new java.sql.Date(1582-1900,09,14)
It returns me
1582-10-24
So there is a difference of 10 days. How to solve this problem?
Are you sure that date exists?
Wikipedia says the Gregorian Calender (which is what you are probably using) started on October 15, 1582.
When the new calendar was put in use, the error accumulated in the 13 centuries since the Council of Nicaea was corrected by a deletion of 10 days. The Julian calendar day Thursday, 4 October 1582 was followed by the first day of the Gregorian calendar, Friday, 15 October 1582 (the cycle of weekdays was not affected).
If you need to deal with days before that, you probably have to write some more involved code.
This is due to the calendar being switched from Julian to Gregorian in that year. (The latter has the 100 and 400 leap year corrections that the Julian calendar lacks. This accounts for the 10 day difference that had accumulated.)
Note that some countries - in particular England - did not adopt that calendar until 1752. And Russia, for example, didn't adopt it until well into the 20th century!
As a rule of thumb, if you're working with dates before 1752 then you ought to consult an historian.
I encountered a weird bug while running some code. Here is a simple version to showcase the same.
public class DateTest {
public static void main(String[] args) {
LocalDate decLast = LocalDate.of(2015, 12, 31);
LocalDate novLast = LocalDate.of(2015, 11, 30);
LocalDate octLast = LocalDate.of(2015, 10, 31);
System.out.println(decLast+" "+novLast+" "+octLast);
System.out.println(decLast.format(DateTimeFormatter.ofPattern("dd M YY"))+" "
+novLast.format(DateTimeFormatter.ofPattern("dd M YY"))+" "
+octLast.format(DateTimeFormatter.ofPattern("dd M YY")));
}
}
This returned the following results
2015-12-31 2015-11-30 2015-10-31
31/12/16 30/11/15 31/10/15
Somehow, the 31st Dec 2015 was converted to 31st Dec 2016.
I wrote a for loop to do the same for different years and found that there is variation in many years. The error doesn't exist for any dates below 26th December. Is this a bug or am I missing something here?
The upper case Y is the "week based year", you are looking for the lower case y instead.
From the linked Wikipedia article (emphasis by me):
An ISO week-numbering year (also called ISO year informally) has 52 or 53 full weeks. That is 364 or 371 days instead of the usual 365 or 366 days. The extra week is referred to here as a leap week, although ISO 8601 does not use this term. Weeks start with Monday. The first week of a year is the week that contains the first Thursday of the year (and, hence, always contains 4 January). ISO week year numbering therefore slightly deviates from the Gregorian for some days close to 1 January.
[...]
For example, 29 December 2014 is ISO 2015-W1-1, i.e., it is in year 2015 instead of 2014.
Cf. also: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
In the JSR-310 java.time API in JDK 8, what are the rules for calculating the result of adding a month to a date. In particular, what happens when you add 1 month to a date like January 31st?
LocalDate initial = LocalDate.of(2012, 1, 31); // 31st January 2012
LocalDate result = initial.plusMonths(1);
// what is the result?
Short answer:
In the example, the result will be the last day of February, 2012-02-29.
Explanation:
The question, "what date do you get if you add a month", is one which could be open to interpretation. To avoid this, the java.time API has a clear rule. The result will have the same day-of-month as the input, unless that would be an invalid date, in which case the result is the last day of the month.
Thus, the 31st January plus one month would result in the 31st February, but since that is an invalid date, the result is the last valid date in February, which is 28th or 29th February depending on whether it is a leap year:
// normal case
2011-01-15 plus 1 month = 2011-02-15 // 15 Jan -> 15 Feb
// special rule choosing the last valid day-of-month
2011-01-31 plus 1 month = 2011-02-28 // 31 Jan -> 28 Feb (2011 is normal year)
2012-01-31 plus 1 month = 2012-02-29 // 31 Jan -> 29 Feb (2012 is leap year)
// same rule applies for months other than February
2013-03-31 plus 1 month = 2013-04-30 // 31 Mar -> 30 Apr (only 30 days in April)
The same rule applies whether adding one month or many months and is always based on the resulting month. ie. the month is added first (adjusting the year if necessary), and only then is the day-of-month considered. The same rule also applies when subtracting.
// multiple months works on the month of the result
2013-10-31 plus 4 months = 2014-02-28 // last day of February
2013-10-31 minus 4 months = 2013-06-30 // last day of June
The same rules also apply when adding/subtracting years to/from a date - the years are added, and only then is the day-of-month checked for validity within the month.
// years use the same rule
2012-02-29 plus 1 year = 2013-02-28 // 29th February invalid so adjusted to 28th
If your business logic needs a different rule for month addition, the best approach is to write a TemporalAdjuster or TemporalAmount that packages up your special logic.