Parsing String date to date [duplicate] - java

This question already has answers here:
Java Date year calculation is off by year for two days
(5 answers)
Closed 5 years ago.
I have a date String in this format "YYYY-MM-dd HH::mm:ss". Every time i parse the string i get wrong date.("Sun Dec 29 10:10:10 CET 2013"). The code is below:
DateFormat timeFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
Date startDate = timeFormat.parse("2014-08-10 10:10:10");
System.out.println(startDate);
This returns "Sun Dec 29 10:10:10 CET 2013". How to correctly parse the date String?

Rather than using YYYY you will need to use yyyy.
Y Refers to WEEK_YEAR whereas y refers to YEAR. WEEK_YEARs are based on when the first full week of a year starts (this differs depending on settings), and thus are slightly (and sometimes largely) different from that of YEAR.
See the javadoc:
http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_year

You are using wrong format. You need yyyy instead of YYYY.
If you take a look at SimpleDateFormat documentation you will find that
y Year
Y Week year
where "week year" is in sync with a WEEK_OF_YEAR cycle.
Now, why YYYY returns 2013 for year 2014?
To answer this question you need to understand how calendar determines that week belongs to some year. Rule is quite simple:
week belongs to year XXXX if last N days of this week (usually N=4 but it is determined by getMinimalDaysInFirstWeek from used Calendar) belongs to year XXXX
weeks starts at day which is result from getFirstDayOfWeek. This result depends on Locale but in next examples we will use Monday as first day of week.
Example 1.
Assuming that first day of week is Monday and days required for week to belong to some year is 4 lets try to determine which week is first in year XXXX for January which looks like this:
January XXXX
Mon Tue Wed Thu Fri Sat Sun
27 28 29 30 31 1 2
3 4 5 6 7 8 9
...
Week from first row contains only two days which belongs to year XXXX (to January), 1st and 2nd
27 28 29 30 31 1 2
^^^ ^^^ //days which belong to January
but this is less than number of days required for this week to belong to XXXX year while next week
3 4 5 6 7 8 9
contains 7 days which belong to XXXX year. Since week in first row doesn't belong to year XXXX first week in week year will start 3 January XXXX. This means that if we parse value XXXX with format YYYY we will get 3rd January XXXX.
Example 2.
Now lets say that calendar for year XXXX looks like this
January XXXX
Mon Tue Wed Thu Fri Sat Sun
30 31 1 2 3 4 5
6 7 8 9 10 11 12
...
As you can see in week
30 31 1 2 3 4 5
its last 5 days belong to year XXXX which is more than required 4 days
-> which means that this week belongs to year XXXX,
-> and it is also first week of XXXX year
-> which means that first week of this year starts at 30 December (XXXX-1)
-> which finally means that if you parse such year using YYYY format you will get value XXXX-1.
Example 2 is actually situation from year 2014, which is why year was interpreted as year 2013.
BTW, if you would decide to use format with week year to set month and day you would also need to use special formats which would describe
which week of year you want to set
and which day of week
so instead of M and d you would have to use
w Week in year
u Day number of week (1 = Monday, ..., 7 = Sunday)
(hours, minutes, seconds are part of time rather than date so H m and s are fine in this format)
for instance
DateFormat format = new SimpleDateFormat("YYYY-ww-uu HH:mm:ss");
Date date = format.parse("2004-53-7 10:10:10");
System.out.println(date);
which will be parsed to Sun Jan 02 10:10:10 CET 2005

Related

DateFormatter ofPattern not returning the correct date [duplicate]

This question already has answers here:
Cant parse recently formatted ZonedDateTime Java 8
(1 answer)
Java LocalDate Formatting of 2000-1-2 error [duplicate]
(2 answers)
Difference between year-of-era and week-based-year?
(7 answers)
Closed 4 years ago.
I am using DateTimeFormatter to format my LocalDate which has the value 31 Jan 2019.
When I execute the code below, the correct date is returned:
// 31, Dec, 2018
System.out.println(LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("dd, MMM, yyyy")));
But if I execute the code below, the date is returned with the correct date, month but the wrong year:
// 31, Dec, 2019
System.out.println(LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("dd, MMM, YYYY")));
What I am confused about is that, if I also use the same pattern above and I just minusDays(30) which makes my expected to be 01 Dec 2018, the correct result is returned:
// 01, Dec, 2018
System.out.println(LocalDate.now().minusMonths(1).minusDays(30).format(DateTimeFormatter.ofPattern("dd, MMM, YYYY")));
Could using YYYY in the DateTimeFormatter.ofPattern("dd, MMM, YYYY")) pattern because this?
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
class Example {
public static void main(String[] args) {
/*Today's date is 31st of January 2019*/
// 2018-12-31
System.out.println(LocalDate.now().minusMonths(1));
// 31, Dec, 2018
System.out.println(LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("dd, MMM, yyyy")));
// 31, Dec, 2019
System.out.println(LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("dd, MMM, YYYY")));
// 01, Dec, 2018
System.out.println(LocalDate.now().minusMonths(1).minusDays(30).format(DateTimeFormatter.ofPattern("dd, MMM, YYYY")));
// 31, Dec, 2018
System.out.println(LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("dd, MMM, uuuu")));
}
}
As far as I understood reading the documentation is because of this:
"YY" specifies the week-based year numbering and for normal year numbering, you should use "yy" instead.
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
EDIT:
The week and year numbering in an ISO-8601 calendar is different from a standard Gregorian calendar. Here’s how January 2nd, 2011 would be represented:
Calendar System Week Number Year Number
Standard Gregorian 1 2011
ISO-8601 52 2010
The Gregorian leap cycle, which has 97 leap days spread across 400 years, contains a whole number of weeks (20871). In every cycle there are 71 years with an additional 53rd week (corresponding to the Gregorian years that contain 53 Thursdays). An average year is exactly 52.1775 weeks long; months (​1⁄12 year) average at exactly 4.348125 weeks.
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 sometimes referred to as a leap week, although ISO 8601 does not use this term.
For more info: https://en.wikipedia.org/wiki/ISO_week_date

android java, week number of a date is incorrect

in my android app I'm working on to get the week number of a provided date. but it doesn't give me the correct week number I'm using following code to get the week number.
String format = "dd-MM-yyyy";
SimpleDateFormat df = new SimpleDateFormat(format);
Date date = df.parse(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int week = cal.get(Calendar.WEEK_OF_YEAR);
but this not give me what I'm expecting. for instance lets take January 2016.
As of January 2016 as seen from the above calendar, days belongs to the week number 1 are only 1st,2nd and 3rd. and for the week number 2, relevant days are 4th, 5th, 6th, 7th,8th, 9th and 10th. then for the week number 3, relevant days are 11th, 12th, 13th, 14th, 15th, 16th and 17th and so on. but for the date 12/01/2016 above code gives me week number 2 instead of week number 3. am I doing something wrong or is this the way the function works normally. how can I meet my goal to get the week number as I mention above.
1st, 2nd and 3rd of January are actually week 53 of year 2015. The code is working correctly, your assumptions about week numbering are wrong. The default behaviour of GregorianCalendar is the same as ISO definition for the first week in Wikipedia:
The ISO 8601 definition for week 01 is the week with the year's first
Thursday in it. The following definitions based on properties of this
week are mutually equivalent, since the ISO week starts with Monday:
It is the first week with a majority (4 or more) of its days in January.
Its first day is the Monday nearest to 1 January.
It has 4 January in it. Hence the earliest possible dates are 29 December through 4 January, the latest 4 through 10 January.
It has the year's first working day in it, if Saturdays, Sundays and 1 January are not working days.
If 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in
week 01. If 1 January is on a Friday, it is part of week 53 of the
previous year; if on a Saturday, it is part of week 52 (or 53 if the
previous year was a leap year); if on a Sunday, it is part of week 52
of the previous year.
Found at https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html :
Values calculated for the WEEK_OF_YEAR field range from 1 to 53. The first week of a calendar year is the earliest seven day period starting on getFirstDayOfWeek() that contains at least getMinimalDaysInFirstWeek() days from that year. It thus depends on the values of getMinimalDaysInFirstWeek(), getFirstDayOfWeek(), and the day of the week of January 1.
So your first week will be week 0 because it starts counting from your first full 7 days week. You can change this by setting getMinimalDaysInFirstWeek() to a lower value

Java SimpleDateFormat shifts Date by one year [duplicate]

This question already has answers here:
Y returns 2012 while y returns 2011 in SimpleDateFormat
(5 answers)
Closed 7 years ago.
I'm getting very weird results, which I can not understand.
public class Test {
private static DateFormat df = new SimpleDateFormat("dd.MM.YYYY HH:mm");
public static void main(String[] args) {
Date d = new Date(1356912000000L);
System.out.println(d);
System.out.println(df.format(d));
}
}
Gives the output:
Mon Dec 31 01:00:00 CET 2012
31.12.2013 01:00
I assume that this might be some issues with locales, but that's a shift by a whole year ! May anyone explain why it performs this way ?
YYYY is the week-year, not the calendar year. You want yyyy instead. Here's Java's relevant details:
Week Of Year and Week Year
Values calculated for the WEEK_OF_YEAR field range from 1 to 53. The
first week of a calendar year is the earliest seven day period
starting on getFirstDayOfWeek() that contains at least
getMinimalDaysInFirstWeek() days from that year. It thus depends on
the values of getMinimalDaysInFirstWeek(), getFirstDayOfWeek(), and
the day of the week of January 1. Weeks between week 1 of one year and
week 1 of the following year (exclusive) are numbered sequentially
from 2 to 52 or 53 (except for year(s) involved in the
Julian-Gregorian transition).
The getFirstDayOfWeek() and getMinimalDaysInFirstWeek() values are
initialized using locale-dependent resources when constructing a
GregorianCalendar. The week determination is compatible with the ISO
8601 standard when getFirstDayOfWeek() is MONDAY and
getMinimalDaysInFirstWeek() is 4, which values are used in locales
where the standard is preferred. These values can explicitly be set by
calling setFirstDayOfWeek() and setMinimalDaysInFirstWeek().
A week year is in sync with a WEEK_OF_YEAR cycle. All weeks between
the first and last weeks (inclusive) have the same week year value.
Therefore, the first and last days of a week year may have different
calendar year values.
For example, January 1, 1998 is a Thursday. If getFirstDayOfWeek() is
MONDAY and getMinimalDaysInFirstWeek() is 4 (ISO 8601 standard
compatible setting), then week 1 of 1998 starts on December 29, 1997,
and ends on January 4, 1998. The week year is 1998 for the last three
days of calendar year 1997. If, however, getFirstDayOfWeek() is
SUNDAY, then week 1 of 1998 starts on January 4, 1998, and ends on
January 10, 1998; the first three days of 1998 then are part of week
53 of 1997 and their week year is 1997.
Instead of:
"dd.MM.YYYY HH:mm"
Use:
"dd.MM.yyyy HH:mm"

Java getDate 0000/00/00 return strange value

Why does this happens? For the month and day, I think Java is assuming the previous valid month and day, but I don't understand why year is 2.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date result = sdf.parse("0000/00/00");
System.out.println(result.toString());
Output is:
Sun Nov 30 00:00:00 GMT 2
The Gregorian calendar does not have year 0.
Year 0 corresponds to 1BCE (Before Common Era, also known as BC).
Because you supply 0 for the month and 0 for the day, it rolls back to the previous month and previous year.
I.e. 30-Nov-0002 BCE.
Date#toString does not include BCE / CE suffix. It would be superfluous in the vast majority of cases.
If you are going to work with dates that far back then you need to consult with an historian.
By default SimpleDateFormat tries to parse even incorrect input. You can switch this off using setLenient method:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
sdf.setLenient(false);
Date result = sdf.parse("0000/00/00");
This way you will have an exception which is probably more appropriate in your case:
Exception in thread "main" java.text.ParseException: Unparseable date: "0000/00/00"
at java.text.DateFormat.parse(DateFormat.java:366)
at Snippet.main(Snippet.java:11)
The starting point for Date would be 00010101
ei Year - 1 , Month - Jan and Date - 1
What you have given input is 00000000
Will start with month - 00 means Jan - 1 ie Dec
Day 00 mean 1 Dec - 1 ie 30th Nov
This explains the 1st part of the output. Sun Nov 30 00:00:00 GMT
The year is given 00 that mean year 1 minus 1 . ie 1 BC
And as year rolls back another time for month and date its 2 BC.
Hence the year is shown as 2.

SimpleDateFormat("dd-MMM-YYYY") printing year one year ahead [duplicate]

This question already has answers here:
Y returns 2012 while y returns 2011 in SimpleDateFormat
(5 answers)
Closed 8 years ago.
I am using SimpleDateFormat("dd-MMM-YYYY") in my code, which is giving wrong output.
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-YYYY");
System.out.println("Actual date : "+new Date()+" after Formatting : "+ dateFormat.format(new Date()));
above code is giving :
Actual date : Tue Dec 30 13:51:06 IST 2014 after Formatting : 30-Dec-2015
Above code is print date having Year as 1 year ahead.
and this issue is replicable for 28-31 december 2014 dates only.
Thanks in advance.
--Ajay
You're using YYYY, which is the "ISO-8601 week year". That should almost always be used in conjunction with w, "week in year". You want yyyy to show the normal calendar year.
The reason they're different is that the first ISO-8601 week of a year is the first (Monday to Sunday) week that includes at least 4 days. This means that the first week of the year is the one containing the first Thursday. As January 1st 2015 falls on a Thursday, that means that the week of 2014-12-29 to 2015-01-04 is all "week year 2015, week of year 1". (I'm surprised if you see if for December 28th...)
In other years, the first few days of the year are in week 52 or 53 of the previous year. For example, January 1st 2010 was in week 53 of week-year 2009, and January 1st 2011 was in week 52 of week-year 2010.

Categories