I have the date of several events expressed in milliseconds[1], and I want to know which events are inside the current week and the current month, but I can't figure out how to obtain the first day (day/month/year) of the running week and convert it to milliseconds, the same for the first day of the month.
[1]Since January 1, 1970, 00:00:00 GMT
This week in milliseconds:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
System.out.println("Start of this week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// start of the next week
cal.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println("Start of the next week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
This month in milliseconds:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of the month
cal.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Start of the month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// get start of the next month
cal.add(Calendar.MONTH, 1);
System.out.println("Start of the next month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
The first day of week can be determined with help of java.util.Calendar as follows:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
long firstDayOfWeekTimestamp = calendar.getTimeInMillis();
The first day of month can be determined as follows:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DATE) > 1) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of month.
}
long firstDayOfMonthTimestamp = calendar.getTimeInMillis();
Pretty verbose, yes.
Java 7 will come with a much improved Date and Time API (JSR-310). If you can't switch yet, then you can as far use JodaTime which makes it all less complicated:
DateTime dateTime = new DateTime(timestamp);
long firstDayOfWeekTimestamp = dateTime.withDayOfWeek(1).getMillis();
and
DateTime dateTime = new DateTime(timestamp);
long firstDayOfMonthTimestamp = dateTime.withDayOfMonth(1).getMillis();
java.time
The java.time framework in Java 8 and later supplants the old java.util.Date/.Calendar classes. The old classes have proven to be troublesome, confusing, and flawed. Avoid them.
The java.time framework is inspired by the highly-successful Joda-Time library, defined by JSR 310, extended by the ThreeTen-Extra project, and explained in the Tutorial.
Instant
The Instant class represents a moment on the timeline in UTC.
The java.time framework has a resolution of nanoseconds, or 9 digits of a fractional second. Milliseconds is only 3 digits of a fractional second. Because millisecond resolution is common, java.time includes a handy factory method.
long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
millisecondsSinceEpoch: 1446959825213 is instant: 2015-11-08T05:17:05.213Z
ZonedDateTime
To consider current week and current month, we need to apply a particular time zone.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
In zoneId: America/Montreal that is: 2015-11-08T00:17:05.213-05:00[America/Montreal]
Half-Open
In date-time work, we commonly use the Half-Open approach to defining a span of time. The beginning is inclusive while the ending in exclusive. Rather than try to determine the last split-second of the end of the week (or month), we get the first moment of the following week (or month). So a week runs from the first moment of Monday and goes up to but not including the first moment of the following Monday.
Let's the first day of the week, and last. The java.time framework includes a tool for that, the with method and the ChronoField enum.
By default, java.time uses the ISO 8601 standard. So Monday is the first day of the week (1) and Sunday is last (7).
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
That week runs from: 2015-11-02T00:17:05.213-05:00[America/Montreal] to 2015-11-09T00:17:05.213-05:00[America/Montreal]
Oops! Look at the time-of-day on those values. We want the first moment of the day. The first moment of the day is not always 00:00:00.000 because of Daylight Saving Time (DST) or other anomalies. So we should let java.time make the adjustment on our behalf. To do that, we must go through the LocalDate class.
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
That week runs from: 2015-11-02T00:00-05:00[America/Montreal] to 2015-11-09T00:00-05:00[America/Montreal]
And same for the month.
ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );
That month runs from: 2015-11-01T00:00-04:00[America/Montreal] to 2015-12-01T00:00-05:00[America/Montreal]
YearMonth
Another way to see if a pair of moments are in the same month is to check for the same YearMonth value.
For example, assuming thisZdt and thatZdt are both ZonedDateTime objects:
boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;
Milliseconds
I strongly recommend against doing your date-time work in milliseconds-from-epoch. That is indeed the way date-time classes tend to work internally, but we have the classes for a reason. Handling a count-from-epoch is clumsy as the values are not intelligible by humans so debugging and logging is difficult and error-prone. And, as we've already seen, different resolutions may be in play; old Java classes and Joda-Time library use milliseconds, while databases like Postgres use microseconds, and now java.time uses nanoseconds.
Would you handle text as bits, or do you let classes such as String, StringBuffer, and StringBuilder handle such details?
But if you insist, from a ZonedDateTime get an Instant, and from that get a milliseconds-count-from-epoch. But keep in mind this call can mean loss of data. Any microseconds or nanoseconds that you might have in your ZonedDateTime/Instant will be truncated (lost).
long millis = firstOfWeek.toInstant().toEpochMilli(); // Possible data loss.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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, Java SE 11, and later - 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
Most 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….
Attention!
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
is good idea, but there is some issue:
For example, i'm from Ukraine and calendar.getFirstDayOfWeek() in my country is 2 (Monday).
And today is 1 (Sunday). In this case calendar.add not called.
So, correct way is change ">" to "!=":
while (calendar.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek()) {...
You can use the java.time package (since Java8 and late) to get start/end of day/week/month.
The util class example below:
import org.junit.Test;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
public class DateUtil {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public static LocalDateTime startOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MIN);
}
public static LocalDateTime endOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MAX);
}
public static boolean belongsToCurrentDay(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfDay()) && localDateTime.isBefore(endOfDay());
}
//note that week starts with Monday
public static LocalDateTime startOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
}
//note that week ends with Sunday
public static LocalDateTime endOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
}
public static boolean belongsToCurrentWeek(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfWeek()) && localDateTime.isBefore(endOfWeek());
}
public static LocalDateTime startOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.firstDayOfMonth());
}
public static LocalDateTime endOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.lastDayOfMonth());
}
public static boolean belongsToCurrentMonth(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfMonth()) && localDateTime.isBefore(endOfMonth());
}
public static long toMills(final LocalDateTime localDateTime) {
return localDateTime.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
}
public static Date toDate(final LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());
}
public static String toString(final LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
}
#Test
public void test() {
//day
final LocalDateTime now = LocalDateTime.now();
System.out.println("Now: " + toString(now) + ", in mills: " + toMills(now));
System.out.println("Start of day: " + toString(startOfDay()));
System.out.println("End of day: " + toString(endOfDay()));
System.out.println("Does '" + toString(now) + "' belong to the current day? > " + belongsToCurrentDay(now));
final LocalDateTime yesterday = now.minusDays(1);
System.out.println("Does '" + toString(yesterday) + "' belong to the current day? > " + belongsToCurrentDay(yesterday));
final LocalDateTime tomorrow = now.plusDays(1);
System.out.println("Does '" + toString(tomorrow) + "' belong to the current day? > " + belongsToCurrentDay(tomorrow));
//week
System.out.println("Start of week: " + toString(startOfWeek()));
System.out.println("End of week: " + toString(endOfWeek()));
System.out.println("Does '" + toString(now) + "' belong to the current week? > " + belongsToCurrentWeek(now));
final LocalDateTime previousWeek = now.minusWeeks(1);
System.out.println("Does '" + toString(previousWeek) + "' belong to the current week? > " + belongsToCurrentWeek(previousWeek));
final LocalDateTime nextWeek = now.plusWeeks(1);
System.out.println("Does '" + toString(nextWeek) + "' belong to the current week? > " + belongsToCurrentWeek(nextWeek));
//month
System.out.println("Start of month: " + toString(startOfMonth()));
System.out.println("End of month: " + toString(endOfMonth()));
System.out.println("Does '" + toString(now) + "' belong to the current month? > " + belongsToCurrentMonth(now));
final LocalDateTime previousMonth = now.minusMonths(1);
System.out.println("Does '" + toString(previousMonth) + "' belong to the current month? > " + belongsToCurrentMonth(previousMonth));
final LocalDateTime nextMonth = now.plusMonths(1);
System.out.println("Does '" + toString(nextMonth) + "' belong to the current month? > " + belongsToCurrentMonth(nextMonth));
}
}
Test output:
Now: 2020-02-16T22:12:49.957, in mills: 1581891169957
Start of day: 2020-02-16T00:00:00
End of day: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current day? > true
Does '2020-02-15T22:12:49.957' belong to the current day? > false
Does '2020-02-17T22:12:49.957' belong to the current day? > false
Start of week: 2020-02-10T00:00:00
End of week: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current week? > true
Does '2020-02-09T22:12:49.957' belong to the current week? > false
Does '2020-02-23T22:12:49.957' belong to the current week? > false
Start of month: 2020-02-01T00:00:00
End of month: 2020-02-29T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current month? > true
Does '2020-01-16T22:12:49.957' belong to the current month? > false
Does '2020-03-16T22:12:49.957' belong to the current month? > false
I have created some methods for this:
public static String catchLastDayOfCurrentWeek(String pattern) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
return calendarToString(cal, pattern);
}
public static String catchLastDayOfCurrentWeek(String pattern) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
cal.add(Calendar.WEEK_OF_YEAR, 1);
cal.add(Calendar.MILLISECOND, -1);
return calendarToString(cal, pattern);
}
public static String catchTheFirstDayOfThemonth(Integer month, pattern padrao) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DAY_OF_MONTH, 1);
return calendarToString(cal, pattern);
}
public static String catchTheLastDayOfThemonth(Integer month, String pattern) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.set(cal.get(Calendar.YEAR), month, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
return calendarToString(cal, pattern);
}
public static String calendarToString(Calendar calendar, String pattern) {
if (calendar == null) {
return "";
}
SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
return format.format(calendar.getTime());
}
You can see more here.
To get the first day of the month, simply get a Date and set the current day to day 1 of the month. Clear hour, minute, second and milliseconds if you need it.
private static Date firstDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DATE, 1);
return calendar.getTime();
}
First day of the week is the same thing, but using Calendar.DAY_OF_WEEK instead
private static Date firstDayOfWeek(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, 1);
return calendar.getTime();
}
In this case:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.HOUR_OF_DAY); <---- is the current hour not 0 hour
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
So the Calendar.HOUR_OF_DAY returns 8, 9, 12, 15, 18 as the current running hour.
I think will be better change such line by:
c.set(Calendar.HOUR_OF_DAY,0);
this way the day always begin at 0 hour
Get First date of next month:-
SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
String selectedDate="MM-dd-yyyy like 07-02-2018";
Date dt = df.parse(selectedDate);`enter code here`
calendar = Calendar.getInstance();
calendar.setTime(dt);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + 1);
String firstDate = df.format(calendar.getTime());
System.out.println("firstDateof next month ==>" + firstDate);
A one-line solution using Java 8 features
In Java
LocalDateTime firstOfWeek = LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 1).toLocalDate().atStartOfDay(); // 2020-06-08 00:00 MONDAY
LocalDateTime firstOfMonth = LocalDateTime.now().with(ChronoField.DAY_OF_MONTH , 1).toLocalDate().atStartOfDay(); // 2020-06-01 00:00
// Convert to milliseconds:
firstOfWeek.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
In Kotlin
val firstOfWeek = LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 1).toLocalDate().atStartOfDay() // 2020-06-08 00:00 MONDAY
val firstOfMonth = LocalDateTime.now().with(ChronoField.DAY_OF_MONTH , 1).toLocalDate().atStartOfDay() // 2020-06-01 00:00
// Convert to milliseconds:
firstOfWeek.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
You should be able to convert your number to a Java Calendar, e.g.:
Calendar.getInstance().setTimeInMillis(myDate);
From there, the comparison shouldn't be too hard.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
/**
This Program will display day for, 1st and last days in a given month and year
#author Manoj Kumar Dunna
Mail Id : manojdunna#gmail.com
*/
public class DayOfWeek {
public static void main(String[] args) {
String strDate = null;
int year = 0, month = 0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter YYYY/MM: ");
strDate = sc.next();
Calendar cal = new GregorianCalendar();
String [] date = strDate.split("/");
year = Integer.parseInt(date[0]);
month = Integer.parseInt(date[1]);
cal.set(year, month-1, 1);
System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
cal.add(Calendar.MONTH, 1);
cal.add(Calendar.DAY_OF_YEAR, -1);
System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
}
}
Simple Solution:
package com.util.calendarutil;
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 CalUtil {
public static void main(String args[]){
DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
Date dt = null;
try {
dt = df.parse("23/01/2016");
} catch (ParseException e) {
System.out.println("Error");
}
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
Date startDate = cal.getTime();
cal.add(Calendar.DATE, 6);
Date endDate = cal.getTime();
System.out.println("Start Date:"+startDate+"End Date:"+endDate);
}
}
i use this trick to get the first day of the current month
note the order is
1 for Sunday
2 for Monday
3 for Tuesday
.... and so on
Calendar cal = new GregorianCalendar();
int startDay = cal.get(Calendar.DAY_OF_YEAR) % 7 + 1;
System.out.println(startDay);
public static void main(String[] args) {
System.out.println(getMonthlyEpochList(1498867199L,12,"Monthly"));
}
public static Map<String,String> getMonthlyEpochList(Long currentEpoch, int noOfTerms, String timeMode) {
Map<String,String> map = new LinkedHashMap<String,String>();
int month = 0;
while(noOfTerms != 0) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, month);
calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
Date monthFirstDay = calendar.getTime();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date monthLastDay = calendar.getTime();
map.put(getMMYY(monthFirstDay.getTime()), monthFirstDay + ":" +monthLastDay);
month--;
noOfTerms--;
}
return map;
}
Related
I am getting week number and year from DB(using function DATE_PART('week',alarm_date - (interval '1 days') * 0) AS week, DATE_PART('year',alarm_date) AS yearNo , ISO compliant) and on the basis of week number and year i want to calculate weekStartDate and weekEndDate between user provided startdate and end date with week start date for example {"startDate":"2021-12-28","endDate":"2022-01-06","weekStartDay":"Sunday"}
private String getWeek(LocalDate startTime, LocalDate endTime, int yearNo, int weekNumber, int weekStartDay){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
// make it ISO compliant since postgres is using ISO time to calculate week number
cal.setMinimalDaysInFirstWeek(4);
cal.set(Calendar.YEAR, yearNo);
cal.set(Calendar.WEEK_OF_YEAR, weekNumber);
//ISO week starts on Monday and ends on Sunday
cal.set(Calendar.DAY_OF_WEEK, weekStartDay);// weekStartDay configurabale, as per
//user input Calendar.SUNDAY or Calendar.MONDAY or Calendar.TUEDAY; etc
String weekStartDate = sdf.format(cal.getTime());
cal.add(Calendar.DATE, 6);
String weekEndDate = sdf.format(cal.getTime());
LocalDate weekStart = LocalDate.of(Integer.valueOf(weekStartDate.substring(0, 4)),
Integer.valueOf(weekStartDate.substring(5, 7)), Integer.valueOf(weekStartDate.substring(8)));
if(weekStart.isBefore(startTime)) {
weekStart = startTime;
}
LocalDate weekEnd = LocalDate.of(Integer.valueOf(weekEndDate.substring(0, 4)),
Integer.valueOf(weekEndDate.substring(5, 7)), Integer.valueOf(weekEndDate.substring(8)));
if(weekEnd.isAfter(endTime)) {
weekEnd = endTime;
}
String weekStr = weekStart.toString()+"_"+weekEnd.toString();
return weekStr;
}
But when weekStartDay falls in lastweek of previous year then it gives the wrong vale of weekStartDate and weekStartEnd so please suggest me how to set yearnumber in java
Avinash, not the full answer but in-line with what Tom mentioned. A lot of convinient date time API's can be used since Java-8. Please feel free to customize this approach for the exact logic you may need
import java.time.DayOfWeek;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import static java.time.temporal.IsoFields.WEEK_OF_WEEK_BASED_YEAR;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;
public class SO75013931 {
public static void main(String[] args) {
System.out.println(getWeekStart(LocalDate.parse("2021-12-28"),DayOfWeek.SUNDAY));
System.out.println(getWeekEnd(LocalDate.parse("2021-12-28"),DayOfWeek.SUNDAY));
}
//28-12-2021 TO 01-01-2022 && 02-01-2022 to 06-01-2022
private static String getWeekStart(LocalDate localDate, DayOfWeek weekStartDay) {
LocalDate weekStart = localDate.with(TemporalAdjusters.previous(weekStartDay));
return weekStart.isBefore(localDate) ? localDate.toString(): weekStart.toString();
}
private static String getWeekEnd(LocalDate localDate, DayOfWeek weekStartDay) {
LocalDate weekEnd = localDate.with(TemporalAdjusters.next(weekStartDay.minus(1)));
return weekEnd.isBefore(localDate) ? localDate.toString(): weekEnd.toString();
}
}
This would give
2021-12-28
2022-01-01
Again, the idea was to recommend usage of these API's as opposed to older util API's
I have the string date "3.9.1991". And I want to obtain how many years have passed since the date. For example 23. How can I achieve it using Calendar or Date?
EDIT:
I have been trying this:
private String parseVkBirthday(String birthdayString) {
// 3.9.1991
SimpleDateFormat formatter = new SimpleDateFormat("d.M.yyyy");
String formattedDate = null;
Calendar date = Calendar.getInstance();
int year = 0;
try {
Date currentDate = new Date();
Date birthdayDate = formatter.parse(birthdayString);
Log.d(LOG_TAG, "year1 = " + currentDate.getTime() + " year2 = " + birthdayDate.getTime());
long diff = currentDate.getTime() - birthdayDate.getTime();
birthdayDate.setTime(diff);
date.setTime(birthdayDate);
year = date.get(Calendar.YEAR);
} catch (ParseException e) {
e.printStackTrace();
}
return "" + year;
}
But it returns me 1993.
Answer:
There are while 3 ways for solving this problem:
1) As codeaholicguy answered, we can use Joda-Time library(what I prefer for Android).
2) As Basil Bourque answered, we can use ThreeTen-Backport library for using java.time classes from java 8.
3) And we can use java 8 and classes from java.time.
Thanks to everyone.
Use SimpleDateFormat and Period of Joda-Time library, example below:
String pattern = "dd.MM.yyyy";
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date date = format.parse("3.9.1991");
System.out.println(date);
Period period = new Period(date.getTime(), (new Date()).getTime());
System.out.println(period.getYears());
String fullDate="3.9.1991";
String[] splitDate=fullDate.split(".");
int year=Integer.parseInt(splitDate[2]);
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int passedYears=currentYear-year;
Calendar.YEAR can be used to add or subtract year from current date in the same fashion we added days and month into date.
http://javarevisited.blogspot.in/2012/12/how-to-add-subtract-days-months-years-to-date-time-java.html
sample program:
import java.util.Calendar;
public class Years {
public static void main(String[] args) {
//create Calendar instance
Calendar now = Calendar.getInstance();
System.out.println("Current date : " + (now.get(Calendar.MONTH) + 1)
+ "-"
+ now.get(Calendar.DATE)
+ "-"
+ now.get(Calendar.YEAR));
//add year to current date using Calendar.add method
now.add(Calendar.YEAR,1);
System.out.println("date after one year : " + (now.get(Calendar.MONTH) + 1)
+ "-"
+ now.get(Calendar.DATE)
+ "-"
+ now.get(Calendar.YEAR));
//substract year from current date
now =Calendar.getInstance();
now.add(Calendar.YEAR,-100);
System.out.println("date before 100 years : " + (now.get(Calendar.MONTH) + 1)
+ "-"
+ now.get(Calendar.DATE)
+ "-"
+ now.get(Calendar.YEAR));
}
}
http://forgetcode.com/Java/1568-Adding-or-Subtracting-Years-to-Current-Date#
Based on example code by xrcwrn with the Joda-Time 2.8 library:
// get the current year with #xrcwm's code
Calendar mydate = new GregorianCalendar();
String mystring = "3.9.1991";
Date thedate = new SimpleDateFormat("d.m.yyyy", Locale.ENGLISH).parse(mystring);
DateTime myDateTime = new DateTime(thedate.getTime()); // joda DateTime object
// get he current date
DateTime currentDateTime = new DateTime();
// get the years value
long years = Years.between(currentDateTime, myDateTime).getYears()
The code above should give you the correct value. Mind you, this code may have some syntax errors.
As a side note, Java 8 has a time package which seems to provide more of the same functionality.
java.time
The new java.time package in Java 8 and later supplants the old java.util.Date/.Calendar & SimpleTextFormat classes.
First parse the string using new DateTimeFormatter class. Do not use SimpleTextFormat. And read the doc as there may be subtle differences in the symbol codes between the old and new classes.
Get today's date, to calculate elapsed years. Note that we need a time zone. Time zone is crucial in determining a date. A new day dawns earlier in Paris, for example, than it does in Montréal.
The Period class considers a span of time as a number of years, months and days not tied to any points on the timeline.
The between method uses the "Half-Open" approach common to date-time handling. The beginning is inclusive while the ending is exclusive.
The default formatting of java.time follows the ISO 8601 standard. Apply formatter if you wish a different string representation of your date-time values.
String input = "3.9.1991" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d.M.yyyy") ;
LocalDate then = LocalDate.parse( input, formatter ) ;
ZoneId zone = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( zone ) ; // Specify time zone to get your locality’s current date.
Period period = Period.between( then , today ) ;
int years = period.getYears() ;
System.out.println( "Between " + then + " and " + today + " is " + years + " years.");
Between 1991-09-03 and 2015-07-09 is 23 years.
Joda-Time
Android currently lacks Java 8 features. So you cannot use java.time. Unless perhaps the ThreeTen-Backport project (a) supports the classes used in the above example and (b) works on Android (I do not know about either).
Alternatively, you can use Joda-Time, the third-party library that inspired java.time. The Joda-Time code version of the above code example would be very similar. In this case, java.time and Joda-Time parallel one another with similar classes.
Calendar mydate = new GregorianCalendar();
String mystring = "3.9.1991";
Date thedate = new SimpleDateFormat("d.m.yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("year -> "+mydate.get(Calendar.YEAR));
Reference
I want to get day names between two dates with simple Java, without using any third party library.
I want to get names like Saturday, Sunday, Monday between two days inclusive both.
/**
*
* #param startDate
* #param endDate
* #return Start Date and End Date are <b>Inclusive</b>, days returned between these two dates
*/
protected List<String> getWeekDayNames(Date startDate, Date endDate) {
List<String> days = new ArrayList<String>();
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);
if (startCal.getTimeInMillis() == endCal.getTimeInMillis()) {
days.add(this.formatDayOfWeek(startCal.getTime()));
return Collections.unmodifiableList(days);
}
// swap values
if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) {
startCal.setTime(endDate);
endCal.setTime(startDate);
}
do {
days.add(this.formatDayOfWeek(startCal.getTime()));
startCal.add(Calendar.DAY_OF_MONTH, 1);
} while (startCal.getTimeInMillis() <= endCal.getTimeInMillis());
return Collections.unmodifiableList(days);
}
Usage:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 15);
List<String> list = new Test().getWeekDayNames(new Date(), cal.getTime());
System.out.println(list);
Output:
[SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
Joda-Time
Usually I would suggest the Joda-Time library, a popular replacement for the notoriously troublesome java.util.Date & java.util.Calendar classes bundled with Java. But the Question requires no third-party libraries.
java.time.*
So, instead of Joda-Time, my code example below uses the new java.time.* package bundled with Java 8. These classes are inspired by Joda-Time, but are entirely re-architected. They are defined by JSR 310. For more information, see the new Tutorial from Oracle.
The solution is quite simple. Boils down to this one-line fragment…
DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, Locale.US );
For fun, I tossed in an extra line to show how easy it is to localize. In this case I show the French as well as US English word for day-of-week.
Here is the entire snippet, ready to run if you import java.time.* and java.time.format.*.
ZoneId timeZone = ZoneId.of( "America/New_York" );
ZonedDateTime start = ZonedDateTime.now( timeZone );
ZonedDateTime stop = start.plusDays( 2 );
// Usually spans of time are handled in a "half-open" manner, meaning start is inclusive and stop is exclusive.
// But the Question required both start and stop to be inclusive. So add "1".
long days = java.time.temporal.ChronoUnit.DAYS.between( start, stop ) + 1L;
System.out.println( days + " days from " + start + " to " + stop + " inclusive…");
for ( int i = 0; i < days; i++ ) {
ZonedDateTime zonedDateTime = start.plusDays( i );
String dayOfWeek = DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, java.util.Locale.US );
String dayOfWeek_Français = DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, java.util.Locale.FRENCH );
System.out.println( "zonedDateTime: " + zonedDateTime + " dayOfWeek: " + dayOfWeek + " dayOfWeek_Français: " + dayOfWeek_Français );
}
When run…
3 days from 2014-02-08T06:06:33.335-05:00[America/New_York] to 2014-02-10T06:06:33.335-05:00[America/New_York] inclusive…
zonedDateTime: 2014-02-08T06:06:33.335-05:00[America/New_York] dayOfWeek: Saturday dayOfWeek_Français: samedi
zonedDateTime: 2014-02-09T06:06:33.335-05:00[America/New_York] dayOfWeek: Sunday dayOfWeek_Français: dimanche
zonedDateTime: 2014-02-10T06:06:33.335-05:00[America/New_York] dayOfWeek: Monday dayOfWeek_Français: lundi
I want to convert the time stamp (epoch time) to human readable string.
For that i am using calendar.setTimeInMillis(timeSinceEpoch) function to create the calender object and to get the date time string in human readable format.
I am confused on, How can I find out that the time stamp (epoch time) is of today or yesterday or it is in the same week as per the system's current date and time?
Is there any API's to achieve this in android?
Thanks.
You can use methods:
public static long diff(long time, int field) {
long fieldTime = getFieldInMillis(field);
Calendar cal = Calendar.getInstance();
long now = cal.getTimeInMillis();
return (time/fieldTime - now / fieldTime);
}
private static final long getFieldInMillis(int field) {
// TODO cache values
final Calendar cal = Calendar.getInstance();
long now = cal.getTimeInMillis();
cal.add(field, 1);
long after = cal.getTimeInMillis();
return after - now;
}
and use them this way:
diff(time, Calendar.DAY_OF_YEAR); // 0 - today, 1 - tomorrow, -1 - yesterday
diff(time, Calendar.WEEK_OF_YEAR); // 0 - this week, -1 - last week etc.
Its really simple:
Calendar c=Calendar.getInstance();
c.getTimeInMillis();
String cur_day=String.format("%te %B %tY",c,c,c); // This will give date like 22 February 2012
c.setTimeInMillis(time);//set your saved timestamp
String that_day=String.format("%te %B %tY",c,c,c); //this will convert timestamp into format like 22 February 2012
//you can compare days,months,year,hours,minutes,seconds and milliseconds using above method.you can find various formats in below link
For more formats,please refer http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html
You can try to use this for detect today date:
public static boolean isDateToday(long milliSeconds) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
Date getDate = calendar.getTime();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date startDate = calendar.getTime();
return getDate.compareTo(startDate) > 0;
}
i think this is the most efficient way of figuring out if two timestamps are on the same day. plus it's language-independent:
int secondsInADay = 60*60*24;
int daysSinceEpoch1 = timestamp1/secondsInADay;
int daysSinceEpoch2 = timestamp2/secondsInADay;
if( daysSinceEpoch1 == daysSinceEpoch2 )
;//sameday
else if( daysSinceEpoch1 - daysSinceEpoch2 == 1 )
;//timestamp2 is a day before timetamp1
else if( ......
set timestamp1 to the current time if you want to compare to today
java.time
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat etc.) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Solution using java.time, the modern API:
The modern date-time API is rich with intuitive concepts e.g. it provides us with the class, Instant which represents an instantaneous point on the timeline. There is a class called ZonedDateTime which represents a date-time with a time-zone in the ISO-8601 calendar system. In order to switch to a different time unit (e.g. day, hour, minute, week, month etc.), the API provides methods named as prepositions and other spoken English constructs. Learn more about the modern date-time API from Trail: Date Time.
The concepts like today, yesterday, same week etc. are bounds to a timezone e.g a moment today in London can be tomorrow in Singapore. Also, the start of the week is Locale-sensitive e.g. for Locale.France, it starts on Monday whereas for Locale.US, it starts on Sunday.
Demo:
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
1621533017083L,
1621446617083L,
1621619417083L,
1621189684296L,
1621209600000L,
1621814400000L
).forEach(millis -> {
System.out.println(millis);
System.out.println(Instant.ofEpochMilli(millis));
System.out.println("Today: " + isToday(millis, "Europe/London"));
System.out.println("Yesterday: " + isYesterday(millis, "Europe/London"));
System.out.println("In the current week: " + isInTheSameWeek(millis, "Europe/London"));
System.out.println();
});
}
static boolean isToday(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the next day at this timezone
ZonedDateTime zdtStartOfDayNextDay = LocalDate.now().plusDays(1).atStartOfDay(zoneId);
long millisStartOfDayNextDay = zdtStartOfDayNextDay.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayToday && epochMillis < millisStartOfDayNextDay);
}
static boolean isYesterday(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the day yesterday at this timezone
ZonedDateTime zdtStartOfDayYesterday = LocalDate.now().minusDays(1).atStartOfDay(zoneId);
long millisStartOfDayYesterday = zdtStartOfDayYesterday.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayYesterday && epochMillis < millisStartOfDayToday);
}
static boolean isInTheSameWeek(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
// The start of the week at this timezone
ZonedDateTime zdtStartOfTheWeek = zdtStartOfDayToday.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
long millisStartOfTheWeek = zdtStartOfTheWeek.toInstant().toEpochMilli();
// The start of the next week at this timezone
ZonedDateTime zdtStartOfTheNextWeek = zdtStartOfDayToday.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
long millisStartOfTheNextWeek = zdtStartOfTheNextWeek.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfTheWeek && epochMillis < millisStartOfTheNextWeek);
}
}
Output:
1621533017083
2021-05-20T17:50:17.083Z
Today: true
Yesterday: false
In the current week: true
1621446617083
2021-05-19T17:50:17.083Z
Today: false
Yesterday: true
In the current week: true
1621619417083
2021-05-21T17:50:17.083Z
Today: false
Yesterday: false
In the current week: true
1621189684296
2021-05-16T18:28:04.296Z
Today: false
Yesterday: false
In the current week: false
1621209600000
2021-05-17T00:00:00Z
Today: false
Yesterday: false
In the current week: true
1621814400000
2021-05-24T00:00:00Z
Today: false
Yesterday: false
In the current week: false
ONLINE DEMO
* 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.
time should be in milli seconds
DateUtils.isToday(time)
How would I go about getting the first day of the month? So for January, of this year, it would return Sunday. And then for February it would return Wednesday.
To get the first date of the current month, use java.util.Calendar. First get an instance of it and set the field Calendar.DAY_OF_MONTH to the first date of the month. Since the first day of any month is 1, inplace of cal.getActualMinimum(Calendar.DAY_OF_MONTH), 1 can be used here.
private Date getFirstDateOfCurrentMonth() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
return cal.getTime();
}
You can create a Calendar with whatever date you want and then do set(Calendar.DAY_OF_MONTH, 1) to get the first day of a month.
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, 25);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date firstDayOfMonth = cal.getTime();
DateFormat sdf = new SimpleDateFormat("EEEEEEEE");
System.out.println("First Day of Month: " + sdf.format(firstDayOfMonth));
public int getFirstDay(){
Calendar c=new GregorianCalendar();
c.set(Calendar.DAY_OF_MONTH, 1);
return c.get(Calendar.DAY_OF_WEEK);
}
From there you can see if the int is equal to Calendar.SUNDAY, Calendar.MONDAY, etc.
In the Java 8 you can use the TemporalAdjusters:
This is an example:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
/**
* Dates in Java8
*
*/
public class App {
public static void main(String[] args) {
LocalDate localDate = LocalDate.now();
System.out.println("Day of Month: " + localDate.getDayOfMonth());
System.out.println("Month: " + localDate.getMonth());
System.out.println("Year: " + localDate.getYear());
System.out.printf("first day of Month: %s%n",
localDate.with(TemporalAdjusters.firstDayOfMonth()));
System.out.printf("first Monday of Month: %s%n", localDate
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));
System.out.printf("last day of Month: %s%n",
localDate.with(TemporalAdjusters.lastDayOfMonth()));
System.out.printf("first day of next Month: %s%n",
localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
System.out.printf("first day of next Year: %s%n",
localDate.with(TemporalAdjusters.firstDayOfNextYear()));
System.out.printf("first day of Year: %s%n",
localDate.with(TemporalAdjusters.firstDayOfYear()));
LocalDate tomorrow = localDate.plusDays(1);
System.out.println("Day of Month: " + tomorrow.getDayOfMonth());
System.out.println("Month: " + tomorrow.getMonth());
System.out.println("Year: " + tomorrow.getYear());
}
}
The results would be:
Day of Month: 16
Month: MAY
Year: 2014
first day of Month: 2014-05-01
first Monday of Month: 2014-05-05
last day of Month: 2014-05-31
first day of next Month: 2014-06-01
first day of next Year: 2015-01-01
first day of Year: 2014-01-01
Last in Month Tuesday: 2014-05-27
Day of Month: 17
Month: MAY
Year: 2014
TemporalAdjuster
In java 8 you can use the new LocalDate and LocalTime API.
To achieve the coveted result, give a try to the following. It prints the name of the given day.
import java.time.*;
import java.time.temporal.*;
public class Main {
public static void main(String[] args) {
LocalDate l = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
System.out.println(l.getDayOfWeek());
}
}
Explanation:
now gives you the current date.
by calling with you can pass a TemporalAdjuster which are a key tool for modifying temporal objects.
getDayOfWeek Gets the day-of-week field, which is an enum DayOfWeek.
This includes textual names of the values.
TemporalAdjuster has a brother class, called TemporalAdjusters which contains static methods regarding the adjustments, like the one you are looking for, the firstDayOfMonth
Create java.util.Date or java.util.Calendar object, set date value and use java.text.SimpleDateFormat class method to format it.
Calendar cal=Calendar.getInstance();
cal.set(Calendar.DATE,1);
cal.set(Calendar.MONTH,0);
cal.set(Calendar.YEAR,2012);
SimpleDateFormat sdf=new SimpleDateFormat("EEEE");
System.out.println(sdf.format(cal.getTime()));
java.time
Since Java 8 we can also use YearMonth class which allows us to create LocalDate objects with specified days (first, last). Then We can simply convert these dates to DayOfWeek Enum (Tutorial) and read its name property.
YearMonth ym = YearMonth.of(2012, 1);
String firstDay = ym.atDay(1).getDayOfWeek().name();
String lastDay = ym.atEndOfMonth().getDayOfWeek().name();
System.out.println(firstDay);
System.out.println(lastDay);
result:
SUNDAY
TUESDAY
java.time, soft-coded
The Answer by Pshemo was good and clever, but is hard-coded to English. Let's take a stab at it allowing for localization.
ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Time zone is crucial to determining a date.
YearMonth yearMonth = YearMonth.now( zoneId );
LocalDate firstOfMonth = yearMonth.atDay( 1 );
Formatter
Generate a textual representation of that LocalDate. We specify a desired Locale, in this case CANADA_FRENCH. If omitted, your JVM’s current default Locale is implicitly applied; better to specify explicit Locale.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "EEEE" ).withZone( zoneId ).withLocale( Locale.CANADA_FRENCH ); // Exactly four 'E' letters means full form. http://docs.oracle.com/javase/8/docs/api/java/time/format/TextStyle.html#FULL
String output = formatter.format( firstOfMonth );
Dump to console.
System.out.println( "output: " + output );
When run.
samedi
DayOfWeek Enum
Another route is to use the DayOfWeek enum. This enum includes a getDisplayName method where you specify both the text style (full name versus abbreviation) and a Locale.
DayOfWeek dayOfWeek = firstOfMonth.getDayOfWeek() ;
String output = dayOfWeek.getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANADA_FRENCH ) ;
Simple and tricky answer
val calendar = Date()
val sdf = SimpleDateFormat("yyyy-MM-01 00:00:00", Locale.getDefault())
var result = sdf.format(calendar)
yyyy-MM-01 -> dd change to 01