Why are SQL Server week numbers different to Java week numbers? - java

I'm working on a reporting system using Java 6 and SQL Server 2008. For some queries I want to look at the data by week number. I'm using Java to fill in gaps in the the data to make a continuous time line and I have found that
java.util.Calendar cal = new java.util.GregorianCalendar();
cal.set(2012, 0, 1);
cal.get(Calendar.WEEK_OF_YEAR);
and
org.joda.time.DateTime date = new org.joda.time.DateTime(2012, 01, 01, 0, 0);
date.getWeekOfWeekyear();
return a different week number to
DATEPART(WEEK, '2012-01-01')
Is there an approach to resolving this difference or will I have to choose to use SQL Server or Java week numbers?
TIA

Java is more sophisticated when it comes to calculating week numbers, whereas SQL-Server DATEPART(WEEK... is more simplistic. I found the following documented here
"When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields, Calendar must determine the first week of the month or year as a reference point. The first week of a month or year is defined as the earliest seven day period beginning on getFirstDayOfWeek() and containing at least getMinimalDaysInFirstWeek() "
I think this defaults to the ISO standards which is the first week of the year with a thursday in (Monday-Sunday weeks where at least 4 days are the year). Consider using:
In SQL Server the DATEPART(WEEK, ..) function is much more simplistic, it simply calculates the number of week boundaries (as defined by DATEFIRST) between the first of january, and the input date, so the 1st January will always be week 1. You may wish to consider using:
SELECT DATEPART(ISO_WEEK, '01/01/2012')
This gets the week number as defined by the ISO standards, which is the first week of the year with a thursday in (Monday-Sunday weeks where at least 4 days are the year).
Since, as stated SQL Server is more simplistic in it's calculations, this can't be configured, which means that you will need to configure your week numbers within Java. Simply ensure you set up your calendar in Java with the correct values for getFirstDayOfWeek() and getMinimalDaysInFirstWeek():
public static Calendar getISOCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.setMinimalDaysInFirstWeek(4);
calendar.setFirstDayOfWeek(Calendar.MONDAY);
return calendar;
}
Then you can esnsure consistent week numbers.
public static void main(String args[]) {
Calendar calendar = getISOCalendar();
calendar.set(2012,0,1);
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR));
}
------
52

According to their respective docs, java.util.calendar, joda, and DATEPART all return an integer between 1 and 53 indicating the week. This value is based on what is defined as the first day of the week and the default calendar (e.g. Gregorian, Chinese). I would check your defaults or see what each thinks the first day of the week is.

I think it might have something to do with 2011 and the idea that it has 53 weeks according to SQLServer. Looking at Jan / New Year SQL problems!, this solution might help to handle the SQLServer stuff better:
DATEPART(WEEK, DATEADD(WEEK, -1, '2012-01-01'))

tl;dr
int iso8601WeekNumber =
ZonedDateTime.now( ZoneId.of ( "America/Montreal" ) )
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
Many definitions of a week
There are many definitions of a week.
For some people the first day of a week is a Sunday, others Mondays, and still others some other day.
For some people the first week of the year contains January 1st, while some other folks count the first week as the one containing that start-of-week day mentioned above, while others count week one as containing a specific day-of-week.
So you should never assume the meaning of a "week" or "week number" without studying the documentation.
Avoid legacy date-time classes
In general, you should avoid the old legacy date-time classes bundled with the earliest versions of Java as they are poorly-designed, confusing, and troublesome.
Here specifically, the java.util.Calendar class has a definition of week that varies by locale. So do not use this if you want reliable constant results.
ISO 8601
The ISO 8601 standard defines formats and related issues for date-time values. It specifically defines the meaning of a week and week-of-year:
Week runs from Monday-Sunday, numbered 1-7 where Monday = 1.
Week # 1 contains the first Thursday of the year, yielding 52 or 53 weeks per year.
Joda-Time
The Joda-Time library uses the ISO 8601 standard definition of week and week-of-year.
However, be aware that the Joda-Time project is now in maintenance mode, with the team advising migration to java.time.
java.time
The java.time classes use the ISO 8601 definition of a week: Week # 1 has first Thursday, with week running Monday-Sunday.
The IsoFields class defines a week-based year. We can ask for the:
Week-of-year number (WEEK_OF_WEEK_BASED_YEAR)
Year number of the week-based year (WEEK_BASED_YEAR).
First we get the current date-time.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
Interrogate that date-time object, asking about the standard week-based year.
int week = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekYear = now.get ( IsoFields.WEEK_BASED_YEAR );
Dump to console.
System.out.println ( "now: " + now + " is week: " + week + " of weekYear: " + weekYear );
now: 2016-01-17T20:55:27.263-05:00[America/Montreal] is week: 2 of weekYear: 2016
For more info, see this similar Question: How to calculate Date from ISO8601 week number in Java.
WeekFields
In java.time you can also call upon the WeekFields class, such as WeekFields.ISO.weekBasedYear(). Should have the same effect as IsoFields in later versions of Java 8 or later (some bugs were fixed in earlier versions of Java 8).
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

System.out.println("get date range from week number and year in java");
System.out.println(); // print a blank line
// get the input from the user
Scanner sc = new Scanner(System.in);
System.out.print("Enter the week : ");
int weekNumber = sc.nextInt();
System.out.print("Enter the Year: ");
int year = sc.nextInt() ;
Calendar cal = Calendar.getInstance();
//cal.setTime(new Date());
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekNumber);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println(formatter.format(cal.getTime())); // start date
cal.add(Calendar.DAY_OF_WEEK, 6);
System.out.println(formatter.format(cal.getTime())); // end date

Related

Java 8 LocalDate- determining the year of a yearless Feb-29 date?

My colleague and I have an interesting problem. We work with an old system that only returns date data in the format ddMMM. If the day/month is in the past for the current year, then we are to assume this date applies to next year. Otherwise it applies to the current year.
So today is 4/30/2015. If the system returned records with 12MAR, then that date translates to 3/12/2016. If the date reads 07MAY, then it translates to 5/7/2015.
However, it is unclear how to determine the year for 29FEB since it is a leap year. We cannot instantiate it with a year without the possibility of it throwing an error. We relied on a try/catch when trying to create a LocalDate off it for the current year. If it catches, we assume it belongs to next year.
Is there a more kosher way to do this?
Parse the value as a MonthDay, as that's what you've got.
If the month-day is not February 29th, just handle it as normal
If it is February 29th, you need to special-case it:
Determine whether the current year is a leap year with Year.isLeap(long)
If it is:
If it's currently on or before Feb 29th, then the result is Feb 29th of this year
If it's currently after Feb 29th, you need rules to apply - you could choose March 1st of next year or Feb 28th of next year
If it's not (a leap year this year)
If it's currently on or before Feb 28th, again you need to rules to apply, probably returning March 1st or Feb 28th of this year
If it's currently after Feb 28th, then the date logically belongs to next year...
If next year is a leap year, the result is presumably Feb 29th of next year
If next year is not a leap year, again you need a rule
That's hopefully outlined the three "odd" conditions you need to account for - we don't have enough information to tell you what to do in those conditions.
java.time
The modern way is with the java.time classes. Specifically, MonthDay in your case.
Note that you should always specify a Locale to determine the human language to use in translation of name of month.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMM" , Locale.ENGLISH );
String input = "29FEB";
MonthDay md = MonthDay.parse( input , f );
You can apply this to a year to get a LocalDate object, a date-only value of year-month-day.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
If we are looking at February 29, check for Leap Year. If this is not a Leap Year, then you said you want to move to next year. But what if next year is also not a Leap Year? You need to keep going until you reach a Leap Year.
int yearNumber today.getYear();
LocalDate ld = null;
if( md.equals( MonthDay.of( 2 , 29 ) && ( ! Year.of( today ).isLeap() ) ) {
// If asking for February 29, and this is not a leap year, move to next year, per our business rule.
… keep adding years until you find a year that *is* a leap year.
ld = md.atYear( yearNumber + x );
} else {
ld = md.atYear( yearNumber );
}
Fall back to 28th
This Question had a special business rule about jumping to the following year if the month-day is February 29 in a non-Leap Year. But for other folks be aware the default behavior in java.time is to simply fall back to February 28 when asking for the 29th a non-Leap Year. No exception is thrown.
LocalDate february28 =
MonthDay.of( 2 , 29 )
.atYear( myNonLeapYearNumber ); // 29th becomes 28th.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Calendar Class problems

I am having problems with the Calendar Class.
Calendar cal = Calendar.getInstance ();
int iYear = cal.get (Calendar.YEAR); // get the current year
int iMonth = cal.get (Calendar.MONTH); // month...
int iDay = cal.get (Calendar.); // current day in the month
This... No Workie!! :-(
I used the debugger and found that the YEAR and the DAY_OF_MONTH are correct,
however, the MONTH is 1 (January) when it SHOULD BE 2 (February).
Here is where it gets even more WEIRD:
I then tried cal.clear ();
followed by cal.set (2014, 2, 27); // Today's Date - Feb 27, 2014
and the month was still 1 (i.e. January)
I set the date to days in January, (2014, 1, 1), (2014, 1, 16),etc
It correctly gave me a 1 for the month
After reading and trying many things (and pulling my hair out..)
I set it to a date in the future, my Birthday (2014, 5, 23) and other days.
For those dates, Month was correctly set to 5 (May)
Month in Calendar begins at 0, which means 0 is January, 1 is February, etc.
Java Date and Time API sucks. Use Joda-Time instead.
use constants in Calendar for month: Calendar.JANUARY etc
For example:
cal.set(2014, Calendar.FEBRUARY, 27);
Please see the description provided for MONTH Constant in Calendar Class.
Calendar.MONTH
public static final int MONTH
Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
So if you want to set the date in calendar than use below code snippet.
cal.set(2014, Calendar.FEBRUARY, 28);
I think it will help you.
tl;dr
LocalDate.now()
.getYear()
java.time
The modern approach uses the industry-leading java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Parts
Interrogate for the parts as needed.
int dayOfMonth = ld.getDayOfMonth() ;
int month = ld.getMonthValue() ;
int year = ld.getYear() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Let try this simple program:
import java.util.Calendar;
class CalendarExample {
public static void main(String args[]) {
Calendar calendar = Calendar.getInstance();
System.out.println("Current Date : " + calendar.get(Calendar.DATE));
System.out.println("Current Month : " + calendar.get(Calendar.MONTH));
System.out.println("Current Year : " + calendar.get(Calendar.YEAR));
System.out.print("Current Time : ");
System.out.print(calendar.get(Calendar.HOUR) + ":");
System.out.print(calendar.get(Calendar.MINUTE) + ":");
System.out.print(calendar.get(Calendar.SECOND));
}
}
You get the o/p:
Current Date : 28
Current Month : 1
Current Year : 2014
Current Time : 11:18:3
In Calender class Jan as constant int is 0 , Feb is 1 ... .month constant int value is from 0,1,2..

Converting Julian date to Java date but still cannot get Month

I am trying to get day ,month and year from a Julian date.
String date = "13136";//Julian date
Date convertedDate = new SimpleDateFormat("yyDDD").parse(date);
System.out.println(convertedDate);
It prints
Thu May 16 00:00:00 BST 2013
which is correct.
Now I want to get Day , Month and Year from it
Calendar cal = Calendar.getInstance();
cal.setTime(convertedDate);
System.out.println(cal.get(Calendar.MONTH));
It prints 4 .
It should print 5 instead of 4 . Why is it not printing as correct ? What I have done wrong here?
As per the javadoc of Calendar.MONTH:
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
So months starts from zero so your output 4 is correct, for general usecase in your code it would be safe to add 1 to it unless you use this values as MONTH value in Calendar again.
As the javadocs state, months begin at zero: 0 = January, 1 = February, and so on.
tl;dr
LocalDate.parse (
"13136",
DateTimeFormatter.ofPattern ( "uuDDD" )
).getMonthValue()
5
…for month of May 2013.
Ordinal, not Julian
Your use of the word “Julian” is technically incorrect, though common. Folks seem to confuse day-of-year (1-365 or 1-366) with practice of counting the number of days elapsed since January 1, 4713 BC used in some scientific fields.
The terms “ordinal date” or day-of-year are more clear.
ISO 8601
Your format for ordinal dates is not standard. Whenever possible, use the standard ISO 8601 formats:
YYYY-DDD
YYYYDDD
java.time
The modern way is with the java.time classes that supplant the troublesome old legacy date-time classes.
DateTimeFormatter
Note that the formatting pattern codes in DateTimeFormatter class are similar to the legacy class but not exactly the some.
String input = "13136"; //Julian date
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuDDD" );
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate localDate = LocalDate.parse ( input, f );
Dump to console.
System.out.println ("localDate: " + localDate );
localDate: 2013-05-16
Month
You can ask about the month of that LocalDate. The Month enum pre-defines a dozen objects, one for each month of the year. And unlike the crazy legacy classes, these are sanely numbered 1-12 for January-December.
If you are passing the month number around your code, I suggest you instead pass around these enum objects. Doing so gives you type-safety, valid values, and self-documenting code.
Month month = localDate.getMonth();
You can get the localized name of that month if needed.
String output = month.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.US, Locale.ITALY, whatever.
If you truly do need the number of the month 1-12, ask in either way.
int monthNumber = month.getValue() ;
int monthNumber = localDate.getMonthValue() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Understanding java.util.Calendar WEEK_OF_YEAR [duplicate]

This question already has answers here:
Why dec 31 2010 returns 1 as week of year?
(6 answers)
Closed 5 years ago.
I'm trying to understand how java.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) works, but it seems that I'm missing some points.
String time = "1998-12-31"; // year month day
java.util.Calendar date = java.util.Calendar.getInstance();
date.setTime((new java.text.SimpleDateFormat("yyyy-MM-dd")).parse(time));
System.err.println("Week of year = " + date.get(java.util.Calendar.WEEK_OF_YEAR));
// Week of year = 1 Why ???
Why date.get(java.util.Calendar.WEEK_OF_YEAR) returns 1 for the last week of the year?
Moreover, WEEK_OF_YEAR for "1998-01-01" is 1 and for "1998-12-23" it is 52.
Does anybody have an explanation for this behavior?
From java.util.Calendar javadoc:
First Week
Calendar defines a locale-specific seven day week using two
parameters: the first day of the week and the minimal days in first
week (from 1 to 7). These numbers are taken from the locale resource
data when a Calendar is constructed. They may also be specified
explicitly through the methods for setting their values.
When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields,
Calendar must determine the first week of the month or year as a
reference point. The first week of a month or year is defined as the
earliest seven day period beginning on getFirstDayOfWeek() and
containing at least getMinimalDaysInFirstWeek() days of that month or
year. Weeks numbered ..., -1, 0 precede the first week; weeks numbered
2, 3,... follow it. Note that the normalized numbering returned by
get() may be different. For example, a specific Calendar subclass may
designate the week before week 1 of a year as week n of the previous
year.
So it's locale-specific. In your case, if the week contains days from new year, it is counted as week 1 from the new year.
You can change this behavior by using Calendar#setMinimalDaysInFirstWeek(int).
tl;dr
java.time.LocalDate.parse( "1998-12-31" )
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
53
Or, add a library, and then…
org.threeten.extra.YearWeek.from( // Convert from a `LocalDate` object to a `YearWeek` object representing the entire week of that date’s week-based year.
LocalDate.parse( "1998-12-31" ) // Parse string into a `LocalDate` objects.
).getWeek() // Extract an integer number of that week of week-based-year, either 1-52 or 1-53 depending on the year.
53
Details
I'm trying to understand how java.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) works
Don’t! That class is a bloody mess, and best left forgotten.
The answer by npe is correct. In Calendar, the definition of a week varies by locale. A well-intentioned feature, but confusing.
Standard week definition
There are many ways to define “a week” and “first week of the year”.
However, there is one major standard definition: the ISO 8601 standard. That standard defines weeks of the year, including the first week of the year.
the week with the year's first Thursday
A standard week begins with Monday and ends with Sunday.
Week # 1 of a standard week-based-year has the first Thursday of the calendar-year.
java.time
The java.time classes supplanted the troublesome legacy date-time classes. These modern classes support the ISO 8601 week through the IsoFields class, holding three constants that implement TemporalField:
WEEK_OF_WEEK_BASED_YEAR
WEEK_BASED_YEAR
WEEK_BASED_YEARS
Call LocalDate::get to access the TemporalField.
LocalDate ld = LocalDate.parse( "1998-12-31" ) ;
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;
ld.toString(): 1998-12-31
weekOfWeekBasedYear: 53
yearOfWeekBasedYear: 1998
Notice the day after, the first day of the new calendar year 1999, also is in the same week, week # 53 of week-based 1998.
LocalDate firstOf1999 = ld.plusDays( 1 );
int weekOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_BASED_YEAR ) ;
firstOf1999.toString(): 1999-01-01
weekOfWeekBasedYear_FirstOf1999: 53
yearOfWeekBasedYear_FirstOf1999: 1998
ISO 8601 string format
The ISO 8601 standard defines a textual format as well as a meaning for week-based-year values: yyyy-Www. For a specific date, add day-of-week numbered 1-7 for Monday-Sunday: yyyy-Www-d.
Construct such a string.
String outputWeek = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ; // yyyy-Www
1998-W53
String outputDate = outputWeek + "-" + ld.getDayOfWeek().getValue() ; // yyyy-Www-d
1998-W53-4
YearWeek
This work is much easier if you add the ThreeTen-Extra library to your project. Then use the YearWeek class.
YearWeek yw = YearWeek.from( ld ) ; // Determine ISO 8601 week of a `LocalDate`.
Generate the standard string.
String output = yw.toString() ;
1998-W53
And parse.
YearWeek yearWeek = YearWeek.parse( "1998-W53" ) ;
yearWeek.toString(): 1998-W53
Determine a date. Pass a java.time.DayOfWeek enum object for day-of-week Monday-Sunday.
LocalDate localDate = yw.atDay( DayOfWeek.MONDAY ) ;
localDate.toString(): 1998-12-28
I strongly recommending adding this library to your project. Then you can pass around smart objects rather than dumb ints. Doing so makes your code more self-documenting, provides type-safety, and ensures valid values.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact as history.
The excellent Joda-Time framework uses ISO 8601 for its defaults. Its classes include this week-of-year information. Joda-Time is a popular replacement for the notoriously troublesome java.util.Date & java.util.Calendar classes bundled with Java.
Example Code
Here is some example code to get first moment of the first day of the first week of the year of the current date-time.
Note the call to withTimeAtStartOfDay to get the first moment of the day.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime now = new DateTime( timeZone );
DateTime firstWeekStart = now.withWeekOfWeekyear(1).withDayOfWeek(1).withTimeAtStartOfDay();
DateTime firstWeekStop = firstWeekStart.plusWeeks( 1 );
Interval firstWeek = new Interval( firstWeekStart, firstWeekStop );
Dump to console…
System.out.println( "now: " + now );
System.out.println( "firstWeekStart: " + firstWeekStart );
System.out.println( "firstWeekStop: " + firstWeekStop );
System.out.println( "firstWeek: " + firstWeek );
When run…
now: 2014-02-07T12:49:33.623+01:00
firstWeekStart: 2013-12-30T00:00:00.000+01:00
firstWeekStop: 2014-01-06T00:00:00.000+01:00
firstWeek: 2013-12-30T00:00:00.000+01:00/2014-01-06T00:00:00.000+01:00

Getting current Year and Month resulting strange results

I am working on a learning project related to Android. I am trying to get current year & month by using below code but it not works for me.
GregorianCalendar gc = new GregorianCalendar();
gc.YEAR // returning 1
gc.MONTH // returning 2
Calendar c = Calendar.getInstance();
c.YEAR // returning 1
c.MONTH // returning 2
Can someone help me? Am i doing something wrong? please forgive me i am new to java development. thanks.
Just to give a bit more background:
Both new GregorianCalendar() and Calendar.getInstance() will correctly give a calendar initialized at the current date and time.
MONTH and YEAR are constants within the Calendar class. You should not use them "via" a reference which makes it look like they're part of the state of an object. It's an unfortunate part of the design of the Calendar class that to access the values of different fields, you need to call get with a field number, specified as one of those constants, as shown in other answers:
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
Note that the month numbers are 0-based, so at the time of this writing (in April) the month number will be 3.
It's an unfortunate part of the design of the Java language that you can reference static members (such as constants) via expressions of that type, rather than only through the type name.
My recommendations:
If your IDE allows it (as Eclipse does), make expressions such as c.YEAR give a compile-time error - you'll end up with much clearer code if you always use Calendar.YEAR.
Where possible, use Joda Time - a much better date/time library for Java. Admittedly on Android you may be a bit space-constrained, but if your app does a lot of date/time manipulation, it would save you a lot of headaches.
Note MONTHS starts from 0..So if you need to map it to practical problems just add +1
int month=c.get(Calendar.MONTH)+1;
int year=c.get(Calendar.YEAR);
int month=c.get(Calendar.MONTH);
System.out.println(year);
System.out.println(month);
tl;dr
YearMonth.now(
ZoneId.of( "America/Montreal" )
)
Details
The Answer by Jon Skeet is correct. You were accessing constants rather than interrogating your own object.
Here is an entirely different alternative, using modern date-time classes.
Avoid legacy date-time classes
The old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.
YearMonth
If you are focused on the year and month without a date, without a time-of-day, and without a time zone, use the YearMonth class.
Rather than pass mere integer numbers around for year and for month, pass around objects of this class. Doing so provides type-safety, ensures valid values, and makes your code more self-documenting.
Determining the current year and month means determining the current date. And for that a time zone is crucial. For any given moment, the date varies around the globe by zone.
ZoneId z = ZoneId.of( "America/Montreal" );
YearMonth ym = YearMonth.now( z );
You can interrogate for its parts.
int year = ym.getYear();
int month = ym.getMonthValue();
This class offers handy methods such as telling you if this is a leap year. You can do math, such as adding/subtracting months/years. You can get a date for any day of this year-month. And more.
Month
Rather than mess around with a mere integer for month, I suggest you use the Month enum. This class has a dozen instances pre-defined, one for each month of the year. As mentioned above, using objects gives you type-safety, valid values, and self-documenting code.
Month m = ym.getMonth();
The class has helpful methods such as generating an localized string with the month’s name.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
Calendar c= Calendar.getInstance()
int cyear = c.get(Calendar.YEAR);//calender year starts from 1900 so you must add 1900 to the value recevie.i.e., 1990+112 = 2012
int cmonth = c.get(Calendar.MONTH);//this is april so you will receive 3 instead of 4.
int cday = c.get(Calendar.DAY_OF_MONTH);
refer this LINK
How to get current Year and Month.
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH) + 1;
int year = calendar.get(Calendar.YEAR);
Very important to add 1 to get the correct month, because the first month value is 0:
int month = calendar.get(Calendar.MONTH) + 1;
MONTH :Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.

Categories

Resources