I am trying to get day of week of first day in selected month. Main condition is use only java.time. I need smth like this:
DayOfWeek dayOfWeek = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).getDayOfWeek();
I already have YearMonth, which i got by entering numbers of year and month. How can i get dayOfWeek of first day in month ? I did it like this:
DayOfWeek dayOfWeek = yearMonth.atDay(1).getDayOfWeek();
but i got a commentary, that i have "magic numbers" that i need eliminate by correct using library java.time.
Magic number
i got a commentary, that i have "magic numbers" that i need eliminate by correct using library java.time.
No, you did not use a magic number; that commentary is incorrect. The author of that commentary jumped too fast upon seeing a hard-coded literal number being passed as an argument. Indeed, passing a literal number as an argument is suspicious as a possible “magic number”, and worthy of a second look, but in this case is quite appropriate.
The term magic number refers to the use of numbers whose purpose/meaning/role is not immediately obvious. Passing 1 to YearMonth.atDay() is quite obvious, meaning the first of the month.
Personally I do wish the YearMonth class offered a atFirstOfMonth like it has atEndOfMonth. My motivation is to avoid this very problem: Being sensitive to spotting hard-coded literal number passed as argument. But no big deal. Your code’s call to atDay( 1 ) is correct and clear. Using a TemporalAdjuster is correct as well, but is not as obvious.
One-liner, if you like short code (I do not):
YearMonth.of( year , month ).atDay( 1 ).getDayOfWeek()
Some discussion follows to elucidate this topic.
YearMonth
I already have YearMonth, which i got by entering numbers of year and month.
Java offers a class for this, to represent an entire month: YearMonth.
YearMonth ym = YearMonth.now() ; // Capture the current year-month as seen through the wall-clock time used by the people of the JVM’s current default time zone.
I recommend passing objects of this class around your codebase rather than using mere integer numbers for year & month. Using objects provides type-safety, ensures valid values, and makes your code more self-documenting.
Time zone
Better to specify a time zone. For any given moment, the date varies around the globe by zone. Better to explicitly specify the desired/expected time zone than rely implicitly on the JVM’s current default which can change at any moment during runtime.
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" ) ; // Specify desired/expected time zone. Or explicitly ask for JVM’s current default: `ZoneId.systemDefault()`.
YearMonth ym = YearMonth.now( z ) ; // Capture the current year-month as seen through the wall-clock time used by the people of a particular region (time zone).
LocalDate
Get the date of the first day of month as a LocalDate.
LocalDate ld = ym.atDay( 1 ) ; // Get the first day of the month.
DayOfWeek
The DayOfWeek enum provides seven pre-existing objects, one for each day of the week. These are not mere strings, but are smart objects.
DayOfWeek dow = ld.getDayOfWeek() ;
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Generate a String representing the name of this day-of-week localized to the human language and cultural norms of a particular `Locale`.
Here is a solution by just passing an LocalDate object:
public static String getFirstWeekDay(LocalDate date) {
int day = 1;
int month = date.getMonthValue();
int year = date.getYear();
LocalDate newDate = LocalDate.of(year, month, day);
String dayOfWeek = newDate.getDayOfWeek().toString();
return dayOfWeek;
}
Alternatively, you could use the method below to get the DayOfWeek Enum:
public static DayOfWeek getFirstWeekDay(LocalDate date){
int day = 1;
int month = date.getMonthValue();
int year = date.getYear();
LocalDate newDate = LocalDate.of(year, month, day);
return newDate.getDayOfWeek();
}
I hope this helps.
If you have the month and the year and you just need the first day of the month I would do something like this:
DayOfWeek firstDay = LocalDate.of(year, month, 1).getDayOfWeek();
Basically, you build a date where the dayOfMonth param is 1.
Based on your solution for the first day of a month assuming yearMonth is a LocalDate this should work:
DayOfWeek dayOfWeek =yearMonth.with(TemporalAdjusters.firstDayOfMonth()).getDayOfWeek();
System.out.println(dayOfWeek);
Related
This question already has answers here:
"cannot find symbol: method" but the method is declared
(3 answers)
How to add one day to a date? [duplicate]
(18 answers)
Closed 3 years ago.
When I try to add 30 days with the date obtained in the Database is giving this error.
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date today = Calendar.getInstance().getTime();
String reportDate = df.format(today);
String endDay = rset.getString("vip_end");
endDay.add(Calendar.DAY_OF_MONTH, 30)
Error
Error:(76, 70) java: cannot find symbol
symbol: method add(int,int)
location: variable endDay of type java.lang.String
tl;dr
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.now( // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Asia/Tokyo" ) // Specify your time zone. Use proper `Continent/Region` names, never 2-4 character pseudo-zones such as IST or PST or EST or CST.
) // Returns a `LocalDate` object.
.plusDays( 30 ) // Add days to determine a later date. Returns a new `LocalDate` object rather than mutating the original.
.toString() // Generate text representing the value of this `LocalDate` object, in standard ISO 8601 format YYYY-MM-DD.
2019-06-30
No add method on String
You declared endDay to be a String. Then you called the method add. But there is no method add on String class. Thus your error, as explained in the error message.
java.time
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes with the adoption of JSR 310. Stop doing that.
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
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 during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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 code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
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. Ditto for Year & YearMonth.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Generating text
Your output format is in standard ISO 8601 format. This format is used by default in the LocalDate class for parsing/generating strings. So no need to specify a formatting pattern.
String output = LocalDate.of( 2019 , Month.JANUARY , 23 ).toString() ;
2019-01-23
Date math
Add 30 days.
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
LocalDate later = today.plusDays( 30 ) ;
The java.time classes follow the immutable objects pattern. So they return a new fresh object based on the values of the original.
I'd like to be able to get a correct DateTime for the NEXT occurrence of a time that I can specify with just an hour and minute. I'd also like to be able to do this by specifying the same thing for that hour and minute, but for the next occurrence of that on (say) a Wednesday.
Also, note that if the current minute has already "started" (which I guess means that we're in 00 milliseconds of that minute) then, again, we need to find the "next" occurrence of that time.
An example with (say) getting a DateTime for the next 10:34 AM and next 12:45 PM that's on a Wednesday, would be greatly appreciated.
How can I do this in Joda?
Something like this, for "next 10:34 AM on a Wednesday:"
DateTime getNextTimeOnDay(int dayOfWeek, int hourOfDay, int minuteOfHour)
{
DateTime now = new DateTime();
DateTime then = now
.withDayOfWeek(dayOfWeek)
.withHourOfDay(hourOfDay)
.withMinuteOfHour(minuteOfHour)
.withSecondOfMinute(0)
.withMillisOfSecond(0);
return then.isBefore(now) ? then.plusWeeks(1) : then;
}
DateTime nextWednesdayAtTenThirtyFour
= getNextTimeOnDay(DateTimeConstants.WEDNESDAY, 10, 34);
// as of now, this is 2012-01-06T10:34:00.000-05:00
java.time
The Answer by Matt Ball is correct for Joda-Time. The makers of Joda-Time have said we should move to the java.time framework built into Java 8 and later as soon as is convenient. So here is the same kind of code rewritten for java.time.
DayOfWeek enum
Since java.time is built into Java, it seems reasonable to replace the argument using an int as the day-of-week with the bundled enum DayOfWeek.
Time Zone
The code in the other Answer has one major issue: It depends implicitly on the JVM’s current default time zone. That default can change at any moment, even during runtime(!). Better to always specify the expected/desired time zone. So I added another argument to our method.
DST Adjustment
If your specified hour and minute land in an anomaly such as Daylight Saving Time (DST), java.time will make an adjustment. Be sure to read the doc to understand that behavior and verify it meets with your desires/expectations.
Using a TemporalAdjustor of next( dayOfWeek ) defined in TemporalAdjustors (notice the plural s) means we will get the next such day, going forward in the future and never the past. So we can drop the ternary test in the return statement.
public ZonedDateTime getNextTimeOnDay ( ZoneId zoneId, DayOfWeek dayOfWeek, int hourOfDay, int minuteOfHour ) {
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime then = now
.with ( TemporalAdjusters.next ( dayOfWeek ) )
.withHour ( hourOfDay )
.withMinute ( minuteOfHour )
.withSecond ( 0 )
.withNano ( 0 );
return then;
}
An example calling that method.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime nextWednesdayAtTenThirtyFour = this.getNextTimeOnDay ( zoneId, DayOfWeek.WEDNESDAY, 10, 34 );
Dump to console.
System.out.println ( nextWednesdayAtTenThirtyFour );
2016-01-20T10:34-05:00[America/Montreal]
By the way, you may want to pass a ZonedDateTime to be used by the method as the starting point rather than assume “now”. This route might be more useful/flexible and facilitate testing. If you choose this route, no need to pass the ZoneId as the passed ZonedDateTime carries with it the assigned time zone.
Writing a Java application that takes user input into a Time and Date class, but I am not sure how to take this user input and convert it into Universal and Standard time... I have spent multiple hours surfing the web and stack overflow and have not been able to find a solution.
I have hours, minutes, seconds, year, month, day all in separate integer variables and need to display them in Universal and Standard time.
Thanks for taking a look...
There are two solutions:
first is place all of input in the string and parse it:
String dateStr = ""
//put your input in this string in some format/ example:
//dateSttr = year + "." + month + "." + day + " " + hour + ":" + minute;
//It is better to use StringBuilder
DateFormat inputFormat = new SimpleDateFormat("yyyy.MM.dd hh:mm");
//note that hh is 12h-format and HH is 24h-format
DateFormat outputFormat1 = new SimpleDateFormat("your_outputFormat");
DateFormat outputFormat2 = new SimpleDateFormat("your_another_outputFormat");
Date date = inputFormat.parse(dateStr);
String o1, o2;
o1 = outputFormat1.format(date);
o2 = outputFormat2.format(date);
//o1 and o2 is your result.
For the rules, how this formats is done, see javadoc
The second solution is to get a new date and set your parameters:
Calendar cln = Calendar.getInstance().clear();
//by default you get a calendar with current system time
//now set the fields. for example, day:
cln.set(Calendar.YEAR, 2015);
cln.set(Calendar.MONTH, Calendar.FEBRUARY);
cln.set(Calendar.DAY_OF_MONTH, 17);
cln.set(Calendar.HOUR_OF_DAY, 18);//Calendar.HOUR for 12h-format
cln.set(Calendar.MINUTE, 27);
See more about setting calendar in javadoc
Note, that in the second variant, you might have some fields undefiend.
If #JonSkeet 's assumption and mine is correct, you're starting with either UTC or your local time. Displaying it is just a matter of formatting your output.
For the other type of time, you add or subtract a number of hours, which you can find on the web. The tricky part is that this may push you into the next calendar day, or pull you back into the previous one. To deal with that, I figure you want to either
implement an adder for year, month, day, hour--or
convert those to decimal somethings (Excel uses days, for instance, where as I write this it's 42328.08813), shift the value by the appropriate number of hours, and convert it back.
java.time
The Answer by TEXHIK is correct, but outdated. Also, as others mentioned, I do not know what you mean by "Universal and Standard time". But I'll try to get you part way there.
As of Java 8, the old java.util.Date/.Calendar classes have been supplanted by the new java.time framework. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
The ZonedDateTime class has a factory method taking numbers for year, month, and so on.
Plus you must specify a time zone. If your numbers represent a date-time in UTC, use the ZoneOffset.UTC constant. For other time zones, specify a ZoneId object by using a proper time zone name; never use the 3-4 letter codes such as EST or IST as their are neither standardized nor unique.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
// ZoneId zoneId = ZoneOffset.UTC; // ZoneOffset is a subclass of ZoneId.
ZonedDateTime zdt = ZonedDateTime.of( 2015 , 1 , 2 , 3 , 4 , 5 , 6 , zoneId );
zdt: 2015-01-02T03:04:05.000000006-05:00[America/Montreal]
You can convert to UTC or another time zone.
ZonedDateTime zdt_Kolkata = zdt.withZoneSameInstant ( ZoneId.of("Asia/Kolkata") );
ZonedDateTime zdt_Utc = zdt.withZoneSameInstant ( ZoneOffset.UTC );
zdt_Kolkata: 2015-01-02T13:34:05.000000006+05:30[Asia/Kolkata]
zdt_Utc: 2015-01-02T08:04:05.000000006Z
If working with classes not yet updated for java.time, convert to a java.util.Date. First extract a Instant object, a moment on the timeline always in UTC.
java.util.Date date = java.util.Date.from ( zdt.toInstant () );
I would like to get which day of the week is the current day and looking the SimpleDateFormat class I tought that the "F" is what I need. So I wrote a little test:
System.out.println(new SimpleDateFormat("F").format(new Date()));
Today is wednesday and I expect to get 3 as output. Instead I get 2.
As english isn't my mothertongue, did I missunderstand the meaning of the format?
F - Day of week in month
E - Day name in week
try u - Day number of week (1 = Monday, ..., 7 = Sunday)
Note that 'u' is since Java 7, but if you need just day number of the week then use Calendar
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_WEEK));
You can change first day of week by changing Locale or directly as
c.setFirstDayOfWeek(Calendar.SUNDAY);
Today is the second Wednesday in the current month.
The java.util.Calendar/.Date and related classes are a confusing mess as you have learned the hard way. Counting from zero for month numbers and day-of-week numbers is one of many poor design choices made in those old classes.
java.time
Those old classes have been supplanted in Java 8 and later by the java.time framework. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
DayOfWeek
For day of week, use the well-named DayOfWeek enum.
If you want an integer for day-of-week compliant with ISO 8601 where Monday = 1 and Sunday = 7, you can extract that from an instance of DayOfWeek.
Conversion
If starting with a java.util.Calendar object, convert to java.time.
An Instant is a moment on the timeline in UTC.
Instant instant = myJavaUtilCalendarObject.toInstant();
Apply a time zone in order to get a date in order to get a day-of-week.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
DayOfWeek dayOfWeek = zdt.getDayOfWeek();
Note that time zone in crucial in determining a date, and therefore a day-of-week. The date is not the same around the world simultaneously. A new day dawns earlier in Paris than in Montréal, for example.
Number Of Day-Of-Week
Now that we have java.time and this enum built into Java, I suggest you freely pass around those enum instances rather than a magic number.
But if you insist on an integer, ask the DayOfWeek.
int dayOfWeekNumber = dayOfWeek.getValue();
String Of Day-Of-Week
That enum generates a localized String for the name of the day-of-week.
String output = dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.ENGLISH.
Indexes for the days of week start from 0, not 1.
F -> Day of week in month(1-5)
Today is - 09/01/2013(dd/MM/yyyy) which fall 2nd in week so it has printed 2.
If you try with 16/01/2013 then it would print 3.
F = Day of Week in Month
1day to 7day, it will print 1.
8day to 14day, it will print 2.
15day to 21day, it will print 3.
22day to 28day, it will print 4 and
29day to 31day, it will print 5.
just use this method for this.
public String day(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("EEEEEEEEE", new Locale("tr", "TR"));
return sdf.format(date);
}
Java's Calendar class provides for two fields: WEEK_OF_MONTH and DAY_OF_WEEK_IN_MONTH. Can someone explain the difference to me? It seems that they both return the same value when tested using the code below:
Calendar date = Calendar.getInstance();
date.set(2011,5,29);
int weekNo1 = date.get(Calendar.WEEK_OF_MONTH);
int weekNo2 = date.get(Calendar.DAY_OF_WEEK_IN_MONTH);
Calendar.WEEK_OF_MONTH simply returns "Current week number in current month"
Calendar.DAY_OF_WEEK simply returns "Current day number in current week starting on last Sunday"
Calendar.DAY_OF_WEEK_IN_MONTH returns "N if current day is Nth day of month" say "3 if today is 3rd Wednesday in month"
So I am writing this on 21st December 2016:
And this is what I am getting:
Calendar today = Calendar.getInstance();
System.out.println(today.get(Calendar.DAY_OF_WEEK)); //outputs 4, as today is 4th day in this week which started on 18
System.out.println(today.get(Calendar.DAY_OF_WEEK_IN_MONTH)); //outputs 3, as today is "3rd Wednesday of this month". Earlier two wednesday were on 7th and 14th
System.out.println(today.get(Calendar.WEEK_OF_MONTH)); //outputs 4, as currently 4th week of a month is running
The difference is that DAY_OF_WEEK_IN_MONTH provides the number of times the weekday has occurred during the month and WEEK_OF_MONTH just returns the week number within the current month. Think of it this way, if the month starts on a Wednesday, the first Monday will occur during the second week of the month. The value for DAY_OF_WEEK_IN_MONTH for that Monday would be 1, but the WEEK_OF_MONTH would be 2.
I found all of the other docs confusing, so for any Microsoft developers like myself this one might be clear for you, as it was for me:
http://msdn.microsoft.com/en-us/library/aa986432(v=vs.80).aspx
A constant representing a value for how many times a given day has
occurred in the month.
You must also take in count that Calendar.getInstance depends on Locale. So, you sometimes could have to specify a concrete Locale instead of the default Locale, for instance: Calendar.getInstance(new Locale("es","PE").
For the example, avobe, Calendar.getInstance(new Locale("es","PE") the calendar will consider first days of the week the Mondays, in other Locales could be other days
tl;dr
Calendar.WEEK_OF_MONTH
Obsolete, never use Calendar.
Means the nth week within a month, with definition varying by Locale and the result of getFirstDayOfWeek().
If you want to define a week as week-of-month # 1 is the week containing day-of-month 1, then use: LocalDate::get( ChronoField.ALIGNED_WEEK_OF_MONTH )
Calendar.DAY_OF_WEEK_IN_MONTH
Obsolete, never use Calendar.
Means the nth day-of-week within that month, such 2nd Tuesday, where weeks are defined as week # 1 containing day 1 of that month.
Replaced by LocalDate::get( ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH )
Avoid Calendar legacy class
Be aware that the Calendar class used in the question is terrible, and was supplanted years ago by the modern java.time classes defined in JSR 310. Do not use Calendar nor GregorianCalendar. They were designed by people who did not understand date-time handling.
java.time
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ; // 2020-01-23.
Convert
If given a Calendar object that is really a GregorianCalendar, you can easily convert to a modern ZonedDateTime object.
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ; // Cast from more general class to the concrete class underlying.
ZonedDateTime zdt = gc.toZonedDateTime() ;
Extract the date-only portion.
LocalDate ld = zdt.toLocalDate() ; // Extract the date, omitting the time-of-day and the context of a time zone.
ChronoField
You can interrogate a LocalDate object via the get method with various ChronoField enum objects.
Calendar.WEEK_OF_MONTH
This asks for the week of the month. But how do you define a week of the month? Unfortunately, the Calendar class’ definition varies by Locale. So your results may vary at runtime.
If your definition is that week # 1 has the first day of the calendar month, you can interrogate a LocalDate using ChronoField.ALIGNED_WEEK_OF_MONTH.
int weekOfMonth = ld.get( ChronoField.ALIGNED_WEEK_OF_MONTH ) ;
Calendar.DAY_OF_WEEK_IN_MONTH
This means the nth day-of-week found in the month, such as 2nd-Tuesday or third-Thursday. Unlike Calendar.WEEK_OF_MONTH, this definition does not vary by Locale. Week # 1 is the week containing day-of-month 1. This legacy Calendar class really is an awful mess, confusing and inconsistent. Good riddance.
Now in java.time, use instead ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH.
DayOfWeek dow = ld.getDayOfMonth() ; // Get enum object representing day of week such as `DayOfWeek.MONDAY`.
int nthDayOfWeekOfMonth = ld.get( ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH ) ;
Week of Month is the week within the current month starting from sundays how many weeks have there been.
Day of week of month is the day 5 would be Thursday, 1 sunday ect.