I know the week number of the year, a week is start from Sunday, then Monday, Tuesday...,Saturday.
Since I know the week number, what's the efficient way to get the dates of the specific week by using Java code??
If you don't want external library, just use calendar.
SimpleDateFormat sdf = new SimpleDateFormat("MM dd yyyy");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.WEEK_OF_YEAR, 23);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println(sdf.format(cal.getTime()));
Pure Java 8 / java.time solution
Based on this:
final long calendarWeek = 34;
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, calendarWeek)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
You can use the joda time library
int weekNumber = 10;
DateTime weekStartDate = new DateTime().withWeekOfWeekyear(weekNumber);
DateTime weekEndDate = new DateTime().withWeekOfWeekyear(weekNumber + 1);
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution:
The first step is to find the first day of the week and as the second step, we just need to iterate all the seven days starting with this date.
Note that the first day of the week is Locale-dependent e.g. it is Monday in the UK while Sunday in the US. As per the ISO 8601 standards, it is Monday. For comparison, check the US calendar and the UK calendar.
Demo of the first step:
import java.time.LocalDate;
import java.time.Year;
import java.time.temporal.WeekFields;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
int weekNumber = 34;
System.out.println(getFirstDayOfWeek(weekNumber, Locale.UK));
System.out.println(getFirstDayOfWeek(weekNumber, Locale.US));
}
static LocalDate getFirstDayOfWeek(int weekNumber, Locale locale) {
return LocalDate
.of(Year.now().getValue(), 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
}
Output:
2021-08-23
2021-08-15
ONLINE DEMO
Demo of the second step:
import java.time.LocalDate;
import java.time.Year;
import java.time.temporal.WeekFields;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
// Test
getAllDaysOfTheWeek(34, Locale.US).forEach(System.out::println);
}
static LocalDate getFirstDayOfWeek(int weekNumber, Locale locale) {
return LocalDate
.of(Year.now().getValue(), 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
static List<LocalDate> getAllDaysOfTheWeek(int weekNumber, Locale locale) {
LocalDate firstDayOfWeek = getFirstDayOfWeek(weekNumber, locale);
return IntStream
.rangeClosed(0, 6)
.mapToObj(i -> firstDayOfWeek.plusDays(i))
.collect(Collectors.toList());
}
}
Output:
2021-08-15
2021-08-16
2021-08-17
2021-08-18
2021-08-19
2021-08-20
2021-08-21
ONLINE DEMO
Learn more about the modern Date-Time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
You did not mention what return type do you exactly need but this code should prove useful to you. sysouts and formatter are just to show you the result.
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.WEEK_OF_YEAR, 30);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(formatter.format(cal.getTime()));
cal.add(Calendar.DAY_OF_WEEK, 6);
System.out.println(formatter.format(cal.getTime()));
This answer is pretty much same as others. But, here it goes:
int year = 2018;
int week = 27;
int day = 1; //assuming week starts from sunday
Calendar calendar = Calendar.getInstance();
calendar.setWeekDate(year, week, day);
System.out.println(calendar.getTime());
for(int i=1; i<=7; i++) {
if(i <= 3) {
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 26)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.of(i)));
System.out.println(desiredDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
} else {
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 26)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.of(i)));
System.out.println(desiredDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
}
}
This snippet provides dates starting from monday to sunday based on the given week number
output:
28/06/2021
29/06/2021
30/06/2021
01/07/2021
02/07/2021
03/07/2021
04/07/2021
To verify check https://www.epochconverter.com/weeks/2021
Related
I am new to using DateTimeFormatter package, and same thing we are able to get using SimpleDateFormat.
Date date = new SimpleDateFormat("MMMM").parse(month);//"DECEMBER"
Date date = new SimpleDateFormat("yyyy").parse(year);//"2020"
How to achive this using DateTimeFormatter?
DateTimeFormatter not supporting with util.Date class, here you need to use LocalDate class. You can't parse only with month or year, you should pass 3 values of month, day and year to get Date.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate parsedDate = LocalDate.parse("2020 12 15", formatter);
System.out.print(parsedDate); //2020-12-15
String monthString = "December";
DateTimeFormatter monthFormatter
= DateTimeFormatter.ofPattern("MMMM", Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
System.out.println(month);
Output:
DECEMBER
Year is somewhat simpler. We don’t need a formatter.
String yearString = "2020";
Year year = Year.parse(yearString);
System.out.println(year);
2020
The old Date class despite its name never represented a date. It was a point in time. Yet we commonly used it for a date, a time of day, a month, a year and still more purposes, sometimes also for the point in time that it was. One very confusing consequence was that the Date objects obtained from the code in your question would under rare circumstances incorrectly print as November instead of December and as 2019 instead of 2020. You should no longer use the Date class. It was always poorly designed and is long outdated.
On the other hand java.time, the modern Java date and time API to which DateTimeFormatter belongs, defines a class for each such concept: LocalDate for a date, Month for a month of year, Year for a year, etc. It makes our code clearer about what we are dealing with, which is good. It also requires us to learn about the different classes and think about which one to use each time.
If your month string was in all uppercase, we need to tell the formatter to parse without regard to case:
String monthString = "DECEMBER";
DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH);
Month month = monthFormatter.parse(monthString, Month::from);
Also when your month name is in English remember to specify an English-speaking locale.
check this link https://www.baeldung.com/java-datetimeformatter.
you can use custom format as
String europeanDatePattern = "dd.MM.yyyy";
DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern);
System.out.println(europeanDateFormatter.format(LocalDate.of(2016, 7, 31)))
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. Let's see them in action:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
Date date1 = new SimpleDateFormat("MMMM").parse("DECEMBER");
System.out.println(date1);
Date date2 = new SimpleDateFormat("yyyy").parse("2020");
System.out.println(date2);
}
}
Output:
Tue Dec 01 00:00:00 GMT 1970
Wed Jan 01 00:00:00 GMT 2020
I do not need to explain what defaults they are taking. Instead of taking such unexpected defaults, they should have raised an alarm (throw some exception) which would have become helpful to a programmer to react to.
Because of such surprises, it is recommended to stop using them completely and switch to the modern date-time API.
Note: For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class Main {
public static void main(String[] args) {
System.out.println(parse("DECEMBER", "MMMM"));
System.out.println(parse("2020", "uuuu"));
}
static LocalDate parse(String text, String pattern) {
try {
return LocalDate.parse(text, DateTimeFormatter.ofPattern(pattern));
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// Return some default value
return LocalDate.MIN;
}
}
}
Output:
Text 'DECEMBER' could not be parsed at index 0
-999999999-01-01
Text '2020' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {Year=2020},ISO of type java.time.format.Parsed
-999999999-01-01
So, now you (the programmer) get to know that you have to do something (e.g. use your own defaults) to parse the strings.
Demo:
import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDate date = parse("DECEMBER", "MMMM");
Month month = parse("DECEMBER", "MMMM").getMonth();
System.out.println(date);
System.out.println(month);
date = parse("2020", "uuuu");
System.out.println(date);
int year = date.getYear();
System.out.println(year);
Year objYear = Year.of(year);
System.out.println(objYear);
}
static LocalDate parse(String text, String pattern) {
LocalDate today = LocalDate.now();
// Formatter using today's day, month and year as defaults
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern(pattern)
.parseDefaulting(ChronoField.DAY_OF_MONTH, today.getDayOfMonth())
.parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue())
.parseDefaulting(ChronoField.YEAR, today.getYear())
.toFormatter(Locale.ENGLISH);
try {
return LocalDate.parse(text, formatter);
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// Return some default value
return LocalDate.MIN;
}
}
}
Output:
2020-12-15
DECEMBER
2020-12-15
2020
2020
If you do not want to create a date or date-time object, rather, if all you want to do is to parse your string into Month and Year, you can do it simply the following way:
import java.time.Month;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Month month = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMMM")
.toFormatter(Locale.ENGLISH)
.parse("DECEMBER", Month::from);
System.out.println(month + " | " + month.getDisplayName(TextStyle.SHORT, Locale.ENGLISH) + " | "
+ month.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
Year year = DateTimeFormatter.ofPattern("uuuu").parse("2020", Year::from);
System.out.println(year);
}
}
Output:
DECEMBER | Dec | December
2020
Learn more about the modern date-time API at Trail: Date Time.
This question already has answers here:
How to get the first date and last date of the previous month? (Java)
(9 answers)
Closed 4 years ago.
String febSt = "02/01/2014" ;
String febEnd = "02/28/2014" ;
Above code is my input i need "03/01/2014" and "03/31/2014" as output .
I tried more codes and used calendar functions also but no result.From this program i need next month start and end date .
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class MonthCalculation {
public void getNextMonth(String date) throws ParseException{
DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date dt = format.parse(date);
Date begining, end;
{
Calendar calendar = getCalendarForNow(dt);
calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
setTimeToEndofDay(calendar);
end = calendar.getTime();
SimpleDateFormat endDt = new SimpleDateFormat("MM/dd/yyyy");
String endStrDt = endDt.format(end);
if(date != null && date.equalsIgnoreCase(endStrDt)){
System.out.println("Ending of the month");
calendar.add(Calendar.DAY_OF_MONTH, 1);
Date lastDate = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String lastDateofNextMonth = sdf.format(lastDate);
System.out.println("Next Month :"+lastDateofNextMonth);
Calendar c = getCalendarForNow(new Date(lastDateofNextMonth));
calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
setTimeToEndofDay(calendar);
end = calendar.getTime();
SimpleDateFormat sfd = new SimpleDateFormat("MM/dd/yyyy");
String lastDated = endDt.format(end);
System.out.println("Testing side :"+lastDated);
}else if (findLeapYear(dt)){
Calendar calendar3 = getCalendarForNow(dt);
calendar3.add(Calendar.YEAR, 1);
Date ds = calendar3.getTime();
SimpleDateFormat dtft = new SimpleDateFormat("MM/dd/yyyy");
String dates = dtft.format(ds);
dtft.setLenient(false);
System.out.println("YEAR : "+dates);
}else{
SimpleDateFormat dtft = new SimpleDateFormat("MM/dd/yyyy");
Calendar calendar2 = getCalendarForNow(dt);
System.out.println(" Calendar time :->> " + dtft.format(calendar2.getTime()));
int curre_month = calendar2.get(Calendar.MONTH);
int curre_day = calendar2.get(Calendar.DAY_OF_MONTH);
int curre_year = calendar2.get(Calendar.YEAR);
Date dat = calendar2.getTime();
calendar2.add(Calendar.DATE, 31);
Date ds = calendar2.getTime();
String dates = dtft.format(ds);
dtft.setLenient(false);
System.out.println("OTHER DAYS : "+dates);
}
}
}
private static boolean findLeapYear(Date dt){
boolean isLeapYr = false;
int yr = dt.getYear();
if ((yr%4 == 0 && yr%100!=0)){
isLeapYr = true;
}
return isLeapYr;
}
private static Calendar getCalendarForNow(Date dt) {
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(dt);
return calendar;
}
private static void setTimeToBeginningOfDay(Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
}
private static void setTimeToEndofDay(Calendar calendar) {
System.out.println("For feb calling");
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
}
public static void main(String[] args) {
try {
String janSt = "01/01/2014" ;
String janEnd = "01/31/2014" ;
String febSt = "02/01/2014" ;
String febEnd = "02/28/2014" ;
String marSt = "03/01/2014" ;
String marEnd = "03/31/2014" ;
String aprilSt = "04/01/2014" ;
String aprilEnd = "04/30/2014" ;
String maySt = "05/01/2014" ;
String mayEnd = "05/31/2014" ;
String juneSt = "06/01/2014" ;
String juneEnd = "06/30/2014" ;
String julySt = "07/01/2014" ;
String julyEnd = "07/31/2014" ;
String augSt = "08/01/2014" ;
String augEnd = "08/31/2014" ;
String sepSt = "09/01/2014" ;
String sepEnd = "09/30/2014" ;
String octSt = "10/01/2014" ;
String octEnd = "10/31/2014" ;
String novSt = "11/01/2014" ;
String novEnd = "11/30/2014" ;
String deceSt = "12/01/2014" ;
String deceEnd = "12/31/2014" ;
String jan15St="01/01/2015";
String jan15End="01/31/2015";
String leapyr = "02/29/2016";
String notaleapyr = "02/28/2015";
new MonthCalculation().getNextMonth(febSt);
} catch (ParseException e) {
e.printStackTrace();
}
}
I tried more with sample inputs , for the months February ,april, june nov start date are not working if i pass these dates as inputs it returns with 2nd of next month
Suggest any idea to proceed further.I am struggling this code.
Thanks in advance
Try this:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
Date nextMonthFirstDay = calendar.getTime();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date nextMonthLastDay = calendar.getTime();
tl;dr
LocalDate.parse( "02/14/2014" , DateTimeformatter.ofPattern( "MM/dd/uuuu" ) )
.with( TemporalAdjusters.firstDayOfNextMonth() )
…and…
LocalDate.parse( "02/14/2014" , DateTimeformatter.ofPattern( "MM/dd/uuuu" ) )
.with( TemporalAdjusters.lastDayOfMonth() )
java.time
The modern way is with the new java.time package bundled with Java 8 (inspired by Joda-Time, defined by JSR 310).
The LocalDate class represents a date-only value without time-of-day and without time zone.
DateTimeFormatter f = DateTimeformatter.ofPattern( "MM/dd/uuuu" );
LocalDate ld = LocalDate.parse( "02/14/2014" , f );
The TemporalAdjuster interface defines a way for implementations to manipulate date-time values. The TemporalAdjusters class provides several handy implementations.
LocalDate firstOfMonth = ld.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate firstOfNextMonth = ld.with( TemporalAdjusters.firstDayOfNextMonth() );
The Question asks for the first and last of the following month, March in this case. We have the first of next month, so we just need the end of that month.
LocalDate lastOfNextMonth = firstOfNextMonth.with( TemporalAdjusters.lastDayOfMonth() );
By the way, as discussed below, the best practice for defining a span of time is the Half-Open approach. That means a month is the first of the month and running up to, but not including, the first of the month after. In this approach we do not bother with determining the last day of the month.
Joda-Time
UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
Easy when using the Joda-Time library and its LocalDate class.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MM/dd/yyyy" );
LocalDate localDate = formatter.parseLocalDate( "02/14/2014" );
LocalDate firstOfMonth = localDate.withDayOfMonth( 1 );
LocalDate nextMonth = localDate.plusMonths(1); // Use this for "half-open" range.
LocalDate endOfMonth = nextMonth.minusDays(1); // Use this for "fully-closed" range.
Half-Open
Tip: Rather than focus on the last moment of a span of time, a better practice is to use the "Half-Open" approach.
In half-open, the beginning is inclusive and the ending is exclusive. So for "a month", we start with the first of the desired month and run up to, but not including, the first of the next month.
February 2014 = 2014-02-01/2014-03-01
Span Of Time
Be aware that Joda-Time provides three handy classes for handling a span of time: Interval, Period, and Duration.
These classes work only with date-time objects (DateTime class) rather than the date-only (LocalDate class) shown in code above.
While not directly relevant to your question, I suspect these span-of-time classes may be helpful.
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, 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 (<26), 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.
Something I quickly wrote for you - so could be cleaned up. Check if this helps:
String string = "02/01/2014"; //assuming input
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date dt = sdf .parse(string);
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.MONTH, 1); //adding a month directly - gives the start of next month.
String firstDate = sdf.format(c.getTime());
System.out.println(firstDate);
//get last day of the month - add month, substract a day.
c.add(Calendar.MONTH, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
String lastDate = sdf.format(c.getTime());
System.out.println(lastDate);
since it is hard to get in your code I have write some coe for you. please check it out..
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.DATE, -1);
Date lastDayOfMonth = calendar.getTime();
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
System.out.println("Today : " + sdf.format(today));
System.out.println("Last Day of Month: " + sdf.format(lastDayOfMonth));
I see the question is old. But I used the DateUtils static methods ceiling and truncate. Came in pretty handy instead of using multiple lines of code.
Date today = new Date();
DateUtils.truncate(new Date(), Calendar.MONTH) // Thu Dec 01 00:00:00 EET 2016
DateUtils.ceiling(new Date(), Calendar.MONTH) // Sun Jan 01 00:00:00 EET 2017
I have a LocalDate which needs to get the first and last day of the month.
How do I do that?
eg. 13/2/2014
I need to get 1/2/2014 and 28/2/2014 in LocalDate formats.
Using threeten LocalDate class.
Just use withDayOfMonth, and lengthOfMonth():
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.getMonth().length(initial.isLeapYear()));
The API was designed to support a solution that matches closely to business requirements
import static java.time.temporal.TemporalAdjusters.*;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());
However, Jon's solutions are also fine.
YearMonth
For completeness, and more elegant in my opinion, see this use of YearMonth class.
YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end = month.atEndOfMonth();
For the first & last day of the current month, this becomes:
LocalDate start = YearMonth.now().atDay(1);
LocalDate end = YearMonth.now().atEndOfMonth();
Jon Skeets answer is right and has deserved my upvote, just adding this slightly different solution for completeness:
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.with(lastDayOfMonth());
LocalDate monthstart = LocalDate.of(year,month,1);
LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);
LocalDate endDate = startDate.withDayOfMonth(1).plusMonths(1).minusDays(1);
or
LocalDate startDate = LocalDate.now();
System.out.println("startDate: "+startDate);
LocalDate firstDayOfMonth_of_startDate = startDate.withDayOfMonth(1);
System.out.println("firstDayOfMonth_of_startDate: "+firstDayOfMonth_of_startDate);
LocalDate firstDayOfNextMonth_of_startDate = firstDayOfMonth_of_startDate.plusMonths(1);
System.out.println("firstDayOfNextMonth_of_startDate: "+firstDayOfNextMonth_of_startDate);
LocalDate lastDayOfTheMonth_of_startDate = firstDayOfNextMonth_of_startDate.minusDays(1);
System.out.println("lastDayOfTheMonth_of_startDate: "+lastDayOfTheMonth_of_startDate);
// or everything in one line
LocalDate endDate = startDate.withDayOfMonth(1).plusMonths(1).minusDays(1);
System.out.println("endDate: "+endDate);
and the printouts
startDate: 2021-11-05
firstDayOfMonth_of_startDate: 2021-11-01
firstDayOfNextMonth_of_startDate: 2021-12-01
lastDayOfTheMonth_of_startDate: 2021-11-30
endDate: 2021-11-30
If anyone comes looking for first day of previous month and last day of previous month:
public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
return date.minusMonths(1).withDayOfMonth(1);
}
public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
return date.withDayOfMonth(1).minusDays(1);
}
Yet another solution for the last day of the month:
I have written this answer just for learners who want to learn by playing with various options. I do not recommend it for production use.
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
//Test
System.out.println(lastDateOfMonth(LocalDate.of(2014, 1, 13)));
System.out.println(lastDateOfMonth(LocalDate.of(2014, 2, 13)));
System.out.println(lastDateOfMonth(LocalDate.of(2016, 2, 13)));
System.out.println(lastDateOfMonth(LocalDate.of(2014, 4, 13)));
}
static LocalDate lastDateOfMonth(LocalDate date) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.DAY_OF_MONTH, 31)
.appendPattern("uuuu-MM")
.toFormatter(Locale.ENGLISH);
return LocalDate.parse(YearMonth.from(date).toString(), dtf);
}
}
Output:
2014-01-31
2014-02-28
2016-02-29
2014-04-30
ONLINE DEMO
How does it work?
The function, YearMonth#toString returns a string in the format, uuuu-MM, the format I have used with the DateTimeFormatterBuilder. I have defaulted the ChronoField.DAY_OF_MONTH to 31, the maximum number of days a month can have, and this works for all months.
Learn more about the modern Date-Time API* from Trail: Date Time.
* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time. Check this answer and this answer to learn how to use java.time API with JDBC.
if you want to do it only with the LocalDate-class:
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = LocalDate.of(initial.getYear(), initial.getMonthValue(),1);
// Idea: the last day is the same as the first day of next month minus one day.
LocalDate end = LocalDate.of(initial.getYear(), initial.getMonthValue(), 1).plusMonths(1).minusDays(1);
You can try this to avoid indicating custom date and if there is need to display start and end dates of current month:
LocalDate start = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()-1);
LocalDate end = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()).plusMonths(1);
System.out.println("Start of month: " + start);
System.out.println("End of month: " + end);
Result:
> Start of month: 2019-12-01
> End of month: 2019-12-30
Try this:
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.getMonthOfYear().getLastDayOfMonth(false));
System.out.println(start);
System.out.println(end);
you can find the desire output but need to take care of parameter true/false for getLastDayOfMonth method
that parameter denotes leap year
Just here to show my implementation for #herman solution
ZoneId americaLaPazZone = ZoneId.of("UTC-04:00");
static Date firstDateOfMonth(Date date) {
LocalDate localDate = convertToLocalDateWithTimezone(date);
YearMonth baseMonth = YearMonth.from(localDate);
LocalDateTime initialDate = baseMonth.atDay(firstDayOfMonth).atStartOfDay();
return Date.from(initialDate.atZone(americaLaPazZone).toInstant());
}
static Date lastDateOfMonth(Date date) {
LocalDate localDate = convertToLocalDateWithTimezone(date);
YearMonth baseMonth = YearMonth.from(localDate);
LocalDateTime lastDate = baseMonth.atEndOfMonth().atTime(23, 59, 59);
return Date.from(lastDate.atZone(americaLaPazZone).toInstant());
}
static LocalDate convertToLocalDateWithTimezone(Date date) {
return LocalDateTime.from(date.toInstant().atZone(americaLaPazZone)).toLocalDate();
}
use withDayOfMonth.
eg. LocalDateTime.now().withDayOfMonth(1)
this will give start of the month.
I have a date string of 1/1/1970 8:00 AM
The correct millis should be 8 hours * 60 minutes per hour * 60000 milliseconds per minute = 28800000
However, using Date.parse(dateString) returns 50400000
What am I not understanding?
Edit
I originally tried using date.getTime();
Here's my original code:
SimpleDateFormat dateFmt = new SimpleDateFormat("MM/dd/yyyy h:mm a");
dateFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
StringBuilder sb = new StringBuilder();
sb.append(month).append("/");
sb.append(day).append("/");
sb.append(year).append(" ");
sb.append(pad(hour)).append(":");
sb.append(pad(minute)).append(" ");;
sb.append(ampm);
Date date = new Date();
date = dateFmt.parse(sb.toString());
date.getTime()
This is almost certainly the problem:
If no time zone is specified, the local time zone is assumed.
My guess is that you're in a time zone which was at UTC-6 at the Unix epoch, so 8am local time was 2pm UTC.
Then there's the more fundamental problem of you using deprecated methods when there are better alternative (SimpleDateFormat, which allows you to set the time zone) available. Methods are deprecated for a reason. You shouldn't just use deprecated methods regardless, otherwise you'll keep running into things like this.
In fact, you'd be better off using Joda Time if you possibly can - but at least stay away from the deprecated methods in Date.
Sample code:
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy h:mm aa", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
long millis = format.parse(text).getTime();
You may want to change dd/MM to MM/dd, depending on what format your dates are going to be in - we can't tell from "01/01". Note the explicit setting of both time zone and locale.
Its because of your local timezone. Use Simple date format with timezone as below to get your desired value against UTC timezone:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
String dateS = "1/1/1970 8:00 AM";
format.setTimeZone(TimeZone.getTimeZone("UTC"));
format.setLenient(true);
Date date = format.parse(dateS);
System.out.println(date.getTime()); //<-- prints 28800000
or more compact:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = format.parse("1/1/1970 8:00 AM");
System.out.println(date.getTime()); //<-- prints 28800000
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
You do not need to form the string: You can use LocalDateTime#of to create an instance of LocalDateTime which can be converted into an Instant in order to get the number of milliseconds from the Unix epoch.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
int year = 1970, month = 1, dayOfMonth = 1, hour = 8, minute = 0;
LocalDateTime ldt = LocalDateTime.of(year, month, dayOfMonth, hour, minute);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
Output:
28800000
ONLINE DEMO
If you already have a date-time string in the given format:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u h:m a", Locale.ENGLISH);
String strDateTime = "1/1/1970 8:00 AM";
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
Output:
28800000
ONLINE DEMO
An Instant represents an instantaneous point on the timeline in UTC.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I want to find out the day of the date in Java for a date like 27-04-2011.
I tried to use this, but it doesn't work:
Calendar cal = Calendar.getInstance();
int val = cal.get(Calendar.DAY_OF_WEEK);
It gives the integer value, not the String output I want. I am not getting the correct value I want. For example it is giving me value 4 for the date 28-02-2011 where it should be 2 because Sunday is the first week day.
Yes, you've asked it for the day of the week - and February 28th was a Monday, day 2. Note that in the code you've given, you're not actually setting the date anywhere - it's just using the current date, which is a Wednesday, which is why you're getting 4. If you could show how you're trying to set the calendar to a different date (e.g. 28th of February) we can work out why that's not working for you.
If you want it formatted as text, you can use SimpleDateFormat and the "E" specifier. For example (untested):
SimpleDateFormat formatter = new SimpleDateFormat("EEE");
String text = formatter.format(cal.getTime());
Personally I would avoid using Calendar altogether though - use Joda Time, which is a far superior date and time API.
Calendar cal=Calendar.getInstance();
System.out.println(new SimpleDateFormat("EEE").format(cal.getTime()));
Output
Wed
See Also
SimpleDateFormat
String dayNames[] = new DateFormatSymbols().getWeekdays();
Calendar date1 = Calendar.getInstance();
System.out.println("Today is a "
+ dayNames[date1.get(Calendar.DAY_OF_WEEK)]);
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice at the Home Page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String input = "27-04-2011";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d-M-u", Locale.ENGLISH);
LocalDate date = LocalDate.parse(input, dtf);
DayOfWeek dow = date.getDayOfWeek();
System.out.println(dow);
// String value
String strDay = dow.getDisplayName(TextStyle.FULL, Locale.ENGLISH);
System.out.println(strDay);
strDay = dow.getDisplayName(TextStyle.SHORT, Locale.ENGLISH);
System.out.println(strDay);
// Alternatively
strDay = date.format(DateTimeFormatter.ofPattern("EEEE", Locale.ENGLISH));
System.out.println(strDay);
strDay = date.format(DateTimeFormatter.ofPattern("EEE", Locale.ENGLISH));
System.out.println(strDay);
}
}
Output:
WEDNESDAY
Wednesday
Wed
Wednesday
Wed
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
See the JavaDoc of the DAY_OF_WEEK field. It points to 7 constants SUNDAY..SATURDAY that show how to decode the int return value of cal.get(Calendary.DAY_OF_WEEK). Are you sure that
Calendar cal = Calendar.getInstance();
cal.set(2011, 02, 28);
cal.get(Calendar.DAY_OF_WEEK);
returns the wrong value for you?
Try following:
Calendar cal=Calendar.getInstance();
int val = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(new DateFormatSymbols().getWeekdays()[val]);
or
Calendar cal=Calendar.getInstance();
String dayName = new DateFormatSymbols().getWeekdays()[cal
.get(Calendar.DAY_OF_WEEK)];
System.out.println(dayName);
Calendar cal=Calendar.getInstance();
cal.set(2011, 2, 28);
int val = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(val);
Look at SimpleDateFormat and propably Locale.
If you need the exact date value in the month you need to use Calendar:DAY_OF_MONTH it will return the exact date in the month starting from 1.
//Current date is 07-06-2021 and this will return 7
Calendar cal = Calendar.getInstance();
int val = cal.get(Calendar.DAY_OF_MONTH);
System.out.println("Date in month:"+val);
//If you want the day of the week in text better use the
//SimpleDateFormat, since Calendar API will return the integer value in
// the week if we given Calendar.DAY_OF_WEEK
String dayWeekText = new SimpleDateFormat("EEEE").format(cal.getTime());
System.out.println("Day of week:"+dayWeekText);
As suggested in the comment Java Date API have all these feature available. Java 8 introduced new APIs for Date and Time to address the shortcomings of the older java.util.Date and java.util.Calendar.
The same can be achieved using Date API in Java
LocalDate localDate = LocalDate.parse("2021-06-08"); //2021 June 08 Tuesday
System.out.println(localDate.dayOfWeek().getAsText()); //Output as : Tuesday
System.out.println(localDate.dayOfWeek().getAsShortText()); //Output as : Tue
System.out.println(localDate.dayOfMonth().get()); //Output as current date