I have dates in variable a and b, like this.
String a = "2016-01-28 21:50";
String b = "2016-01-31 21:49";
How do I count how many days are there between variable a and b?
In Java 8, you can use ChronoUnit to achieve this.
Here is an example code snippet for you to consider.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class DaysInBetween {
public static void main(String[] args) {
String a = "2016-01-28 21:50";
String b = "2016-01-31 21:49";
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
final LocalDate d1 = LocalDate.parse(a, fmt);
final LocalDate d2 = LocalDate.parse(b, fmt);
final long daysInBetween = ChronoUnit.DAYS.between(d1, d2);
System.out.println("Number of days in between:" + daysInBetween);
}
}
Related
I have a:
String fromUser = "2002-10-29";
I would like to output it to Date type (Java.sql.Date) without dashes, and just numbers.
20021029 // yyyyMMdd
How do I achieve it? Thank you,
I've tried using DateFormat, SimpleDateFormat and most of them give me back yyyy-MM-dd.
The documentation in Oracle for Java.util.Date mentioned that the Constructor
Date(int year, int month, int day)
is already deprecated.
Here are three ways to convert a string to java.sql.Date.
Since the string is already in the recognized format, use [static] method valueOf(String) in class java.sql.Date.
Convert the string to a LocalDate and call [static] method valueOf(LocalDate) also in class java.sql.Date.
Convert the string to a date, get the epoch milliseconds and call the constructor of class java.sql.Date.
The below code demonstrates each of the above ways.
import java.sql.Date;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class JdbcTest {
public static void main(String[] args) {
String fromUser = "2002-10-29";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
LocalDate ld = LocalDate.parse(fromUser, dtf);
LocalDateTime ldt = ld.atStartOfDay();
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
Instant inst = zdt.toInstant();
long millis = inst.toEpochMilli();
Date d = new Date(millis);
System.out.println("Constructor: " + d);
d = Date.valueOf(ld);
System.out.println("From LocalDate: " + d);
d = Date.valueOf(fromUser);
System.out.println("From String: " + d);
}
}
When I run the above code using JDK 19 on Windows 10, I get the following:
Constructor: 2002-10-29
From LocalDate: 2002-10-29
From String: 2002-10-29
I am trying to get a list of months (actually the first days of those months) between two dates in Java but I am not getting the expected results.
The start date is "3/17/2020", the end date "3/17/2021" and the expected result is as follows:
"01-Mar-2020"
"01-Apr-2020"
"01-May-2020"
"01-Jun-2020"
"01-Jul-2020"
"01-Aug-2020"
"01-Sep-2020"
"01-Oct-2020"
"01-Nov-2020"
"01-Dec-2020"
"01-Jan-2021"
"01-Feb-2021"
"01-Mar-2021"
Here below is the code I am using:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
String date1 = "3/17/2020";
String date2 = "3/17/2021";
DateFormat formater = new SimpleDateFormat("MM/dd/yyyy");
Calendar beginCalendar = Calendar.getInstance();
Calendar finishCalendar = Calendar.getInstance();
try {
beginCalendar.setTime(formater.parse(date1));
finishCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat formaterYd = new SimpleDateFormat("01-MMM-YYYY");
while (beginCalendar.before(finishCalendar)) {
// add one month to date per loop
String date = formaterYd.format(beginCalendar.getTime()).toUpperCase();
System.out.println(date);
beginCalendar.add(Calendar.MONTH, 1);
}
}
}
With the above code I am getting the following result:
"01-Jan-2020"
"01-Feb-2020"
"01-Mar-2020"
"01-Apr-2020"
"01-May-2020"
"01-Jun-2020"
"01-Jul-2020"
"01-Aug-2020"
"01-Sep-2020"
"01-Oct-2020"
"01-Nov-2020"
"01-Dec-2020"
Please help me understand the issue and suggest any solution for the same with java 7.
I recommend you do it using the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. The java.util date-time API and SimpleDateFormat are outdated and error-prone. In case you are not using Java-8, you can still use Java-8 date-time API through ThreeTenABP library.
If you are doing it in Android and your Android API level is still not compliant with Java8, check Java 8+ APIs available through desugaring.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getDateList("3/17/2020", "3/17/2021"));
}
static List<String> getDateList(String strStartDate, String strEndDate) {
// Formatter for the input
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("M/d/u");
// Formatter for the output
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MMM-uuuu");
// Parse strings to LocalDate instances
LocalDate startDate = LocalDate.parse(strStartDate, inputFormatter);
LocalDate endDate = LocalDate.parse(strEndDate, inputFormatter);
return Stream.iterate(startDate.withDayOfMonth(1), date -> date.plusMonths(1))
.limit(ChronoUnit.MONTHS.between(startDate, endDate.plusMonths(1)))
.map(date -> date.format(outputFormatter))
.collect(Collectors.toList());
}
}
Output:
[01-Mar-2020, 01-Apr-2020, 01-May-2020, 01-Jun-2020, 01-Jul-2020, 01-Aug-2020, 01-Sep-2020, 01-Oct-2020, 01-Nov-2020, 01-Dec-2020, 01-Jan-2021, 01-Feb-2021, 01-Mar-2021]
Using legacy API:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class Main {
public static void main(String[] args) throws ParseException {
// Test
System.out.println(getDateList("3/17/2020", "3/17/2021"));
}
static List<String> getDateList(String strStartDate, String strEndDate) throws ParseException {
// List to be populated and returned
List<String> dateList = new ArrayList<>();
// Formatter for the input
DateFormat inputFormatter = new SimpleDateFormat("M/d/yyyy");
// Formatter for the output
DateFormat outputFormatter = new SimpleDateFormat("dd-MMM-yyyy");
// Parse strings to LocalDate instances
Date startDate = inputFormatter.parse(strStartDate);
Date endDate = inputFormatter.parse(strEndDate);
// Calendar to start with
Calendar startWith = Calendar.getInstance();
startWith.setTime(startDate);
startWith.set(Calendar.DAY_OF_MONTH, 1);
for (Calendar calendar = startWith; calendar.getTime().getTime() <= endDate.getTime(); calendar
.add(Calendar.MONTH, 1)) {
dateList.add(outputFormatter.format(calendar.getTime()));
}
return dateList;
}
}
Output:
[01-Mar-2020, 01-Apr-2020, 01-May-2020, 01-Jun-2020, 01-Jul-2020, 01-Aug-2020, 01-Sep-2020, 01-Oct-2020, 01-Nov-2020, 01-Dec-2020, 01-Jan-2021, 01-Feb-2021, 01-Mar-2021]
Using java.time.LocalDate:
public static List<LocalDate> diff(LocalDate start, LocalDate end) {
return start
.datesUntil(end)
.filter(e -> e.getDayOfMonth() == 1)
.collect(Collectors.toList());
}
diff(LocalDate.now(), LocalDate.of(2020, 12, 20))
Output:
[2020-10-01, 2020-11-01, 2020-12-01]
You can use DateTimeFormatter string date to LocalDate and vice-versa.
EDIT
Using java 7 only (modified given code in question):
public static void main(String[] args) throws IOException {
String date1 = "3/17/2020";
String date2 = "3/17/2021";
DateFormat formater = new SimpleDateFormat("MM/dd/yyyy");
Calendar beginCalendar = Calendar.getInstance();
Calendar finishCalendar = Calendar.getInstance();
try {
beginCalendar.setTime(formater.parse(date1));
finishCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat formaterYd = new SimpleDateFormat("dd-MMM-YYYY");
// mind this condition in while
while (beginCalendar.compareTo(finishCalendar) <= 0) {
Calendar tmp = (Calendar)beginCalendar.clone();
tmp.set(Calendar.DAY_OF_MONTH, 1);
String date = formaterYd.format(tmp.getTime()).toUpperCase();
System.out.println(date);
beginCalendar.add(Calendar.MONTH, 1);
}
}
Java7 soulution:
public static void main(String[] args) throws ParseException {
DateFormat df1 = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
Date dateFrom = df1.parse("3/17/2020");
Date dateTo = df1.parse("3/17/2021");
final Locale locale = Locale.US;
DateFormat df2 = new SimpleDateFormat("MMM-yyyy", Locale.US);
List<String> months = getListMonths(dateFrom, dateTo, locale, df2);
for (String month : months)
System.out.println(month.toUpperCase(locale));
}
public static List<String> getListMonths(Date dateFrom, Date dateTo, Locale locale, DateFormat df) {
Calendar calendar = Calendar.getInstance(locale);
calendar.setTime(dateFrom);
List<String> months = new ArrayList<>();
while (calendar.getTime().getTime() <= dateTo.getTime()) {
months.add(df.format(calendar.getTime()));
calendar.add(Calendar.MONTH, 1);
}
return months;
}
Output:
MAR-2020
APR-2020
MAY-2020
JUN-2020
JUL-2020
AUG-2020
SEP-2020
OCT-2020
NOV-2020
DEC-2020
JAN-2021
FEB-2021
MAR-2021
My Sunday challenge is to get and persist working days in a particular year to a CSV, etc file.
I have following code and the problem I am facing is : how to print dates in a specific format i.e. YYYYMMDD as the code currently prints something like Sat Jan 19 00:00:00 CET 2019.
Also, if I can exclude week-ends and generally if there is a better way to write a much shorter code in Java 8.
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;
public class DatesInYear
{
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
public static void main (String[] args) throws java.lang.Exception
{
Date dt = new Date();
System.out.println(dt);
List<Date> dates = printDates("20190101","20191231");
Collections.reverse(dates);
System.out.println(dates.size());
for(Date date:dates)
{
SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd");
System.out.println(format1.format(date));
}
}
public static List<Date> printDates(String fromDate, String toDate)
{
ArrayList<Date> dates = new ArrayList<Date>();
try {
Calendar fromCal = Calendar.getInstance();
fromCal.setTime(dateFormat .parse(fromDate));
Calendar toCal = Calendar.getInstance();
toCal.setTime(dateFormat .parse(toDate));
while(!fromCal.after(toCal))
{
dates.add(fromCal.getTime());
fromCal.add(Calendar.DATE, 1);
}
} catch (Exception e) {
System.out.println(e);
}
return dates;
}
}
Since it's 2020, you really should be embracing the java.time.* API.
While I'm sure there's probably a really neat way to get the "working" days between to dates, I've gone for the brute force method...
LocalDate ld = LocalDate.of(2020, Month.JANUARY, 1);
LocalDate endDate = ld.plusYears(1);
// You don't "have" to put into a list, but I like to seperate my
// code responsbilities ;)
List<LocalDate> workDays = new ArrayList<>(365);
System.out.println(endDate);
while (ld.isBefore(endDate)) {
// This would be a good place for a delegate to determine if we want the specific day
// as it could then take into account public holidays
if (ld.getDayOfWeek() == DayOfWeek.SATURDAY || ld.getDayOfWeek() == DayOfWeek.SUNDAY) {
// NOOP
} else {
workDays.add(ld);
}
ld = ld.plusDays(1);
}
Then you can simply use a DateTimeFormatter to format the LocalDate into a format that you want, for example...
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMdd");
List<String> formats = workDays.stream().map(value -> value.format(format)).collect(Collectors.toList());
for (String value : formats) {
System.out.println(value);
}
Set<DayOfWeek> weekend = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
LocalDate.of(2019, Month.JANUARY, 1)
.datesUntil(LocalDate.of(2020, Month.DECEMBER, 31), Period.ofDays(1))
.filter(x -> !weekend.contains(x.getDayOfWeek()))
.forEachOrdered(System.out::println);
Here's 2 slightly different takes on your problem:
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class DatesInYear {
public static void main(final String[] args) throws Exception {
listWorkingDays(2020).forEach(System.out::println);
}
private static List<LocalDate> listWorkingDays(final int year) {
IntStream
.rangeClosed(1, LocalDate.ofYearDay(year + 1, 1).minusDays(1).getDayOfYear())
.mapToObj (day -> LocalDate.ofYearDay(year, day))
.filter (date -> date.getDayOfWeek().getValue() <= 5)
.forEach (System.out::println);
return IntStream
.rangeClosed(1, LocalDate.ofYearDay(year + 1, 1).minusDays(1).getDayOfYear())
.mapToObj (day -> LocalDate.ofYearDay(year, day))
.filter (date -> date.getDayOfWeek().getValue() <= 5)
.collect (Collectors.toList());
}
}
A lucid way to display all weekdays in a date range using Java 8 and modern date-time API is as follows:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<LocalDate> dates = getDates("2019-01-01", "2019-12-31");
for (LocalDate date : dates) {
System.out.println(DateTimeFormatter.BASIC_ISO_DATE.format(date));
}
}
public static List<LocalDate> getDates(String fromDate, String toDate) {
LocalDate startDate = LocalDate.parse(fromDate);
LocalDate endDate = LocalDate.parse(toDate).plusDays(1);
long range = ChronoUnit.DAYS.between(startDate, endDate);
return Stream.iterate(startDate, date -> date.plusDays(1)).limit(range)
.filter(d -> !(d.getDayOfWeek() == DayOfWeek.SATURDAY || d.getDayOfWeek() == DayOfWeek.SUNDAY))
.collect(Collectors.toList());
}
}
Output:
20190101
20190102
20190103
20190104
20190107
20190108
...
...
...
20191226
20191227
20191230
20191231
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<LocalDate> dates = getDates("2019-01-01", "2019-12-31");
for (LocalDate date : dates) {
System.out.println(DateTimeFormatter.BASIC_ISO_DATE.format(date));
}
}
public static List<LocalDate> getDates(String fromDate, String toDate) {
LocalDate startDate = LocalDate.parse(fromDate);
LocalDate endDate = LocalDate.parse(toDate).plusDays(1);
long range = ChronoUnit.DAYS.between(startDate, endDate);
return Stream.iterate(startDate, date -> date.plusDays(1)).limit(range)
.filter(d -> !(d.getDayOfWeek() == DayOfWeek.SATURDAY || d.getDayOfWeek() == DayOfWeek.SUNDAY))
.collect(Collectors.toList());
}
}
try this:
// Using Java 8
DateTimeFormatter oldPattern = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter newPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime datetime = LocalDateTime.parse(input, oldPattern);
output = datetime.format(newPattern);
System.out.println("old format date: " + input);
System.out.println("new format date : " + output);
I have a text box for time that takes input as String and I have to convert it to a format that has a space between the number and AM or PM.
Eg: 5:00PM has to be converted into 5:00 PM
Here is an example using in Date/Time formatting features.
Note that it will throw parse errors if the input is not in the correct format.
If the AM/PM segment is guaranteed to be upper case the toUpperCase() call can be removed.
package com.stackoverflow.q42913242;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
#SuppressWarnings("javadoc")
public class Answer {
static final DateTimeFormatter FROM_PATTERN = DateTimeFormatter.ofPattern("h:mma");
static final DateTimeFormatter TO_PATTERN = DateTimeFormatter.ofPattern("h:mm a");
public static void main(String[] args) {
System.out.println(convert("5:00pm"));
System.out.println(convert("12:00AM"));
}
public static String convert(String input) {
final LocalTime localTime = LocalTime.parse(input.toUpperCase(), FROM_PATTERN);
return localTime.format(TO_PATTERN);
}
}
You can use substring for it, eg.:
String time = "5:00PM";
String newTime = time.substring(0,time.length()-2) + " " + time.substring(time.length()-2);
Can I get localized short day-in-week name (Mo/Tu/We/Th/Fr/Sa/Su for English) in Java?
The best way is with java.text.DateFormatSymbols
DateFormatSymbols symbols = new DateFormatSymbols(new Locale("it"));
// for the current Locale :
// DateFormatSymbols symbols = new DateFormatSymbols();
String[] dayNames = symbols.getShortWeekdays();
for (String s : dayNames) {
System.out.print(s + " ");
}
// output : dom lun mar mer gio ven sab
If standard abbreviations are fine with you, just use Calendar class like this:
myCal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.US);
An example using SimpleDateFormat:
Date now = new Date();
// EEE gives short day names, EEEE would be full length.
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE", Locale.US);
String asWeek = dateFormat.format(now);
SimpleDateFormat as been around longer than the C-style String.format and System.out.printf, and I think you'd find most Java developers would be more familiar with it and more in use in existing codebases, so I'd recommend that approach.
java.time
Update for those using Java 8 and later.
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
Instant instant = Instant.now();
ZonedDateTime zDateTime = instant.atZone(zoneId);
DayOfWeek day = zDateTime.getDayOfWeek();
Show output.
System.out.println(day.getDisplayName(TextStyle.SHORT, Locale.US));
System.out.println(day.getDisplayName(TextStyle.NARROW, Locale.US));
When run. See similar code run live at IdeOne.com.
Tue
T
DateTimeFormatter#localizedBy
Starting with Java SE 10, you can use DateTimeFormatter#localizedBy.
Demo:
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtfHindi = DateTimeFormatter.ofPattern("E").localizedBy(Locale.forLanguageTag("hi"));
DateTimeFormatter dtfBangla = DateTimeFormatter.ofPattern("E").localizedBy(Locale.forLanguageTag("bn"));
DateTimeFormatter dtfGerman = DateTimeFormatter.ofPattern("E").localizedBy(Locale.forLanguageTag("de"));
DateTimeFormatter dtfEnglish = DateTimeFormatter.ofPattern("E").localizedBy(Locale.forLanguageTag("en"));
// Replace ZoneId.systemDefault() with the applicable timezone e.g.
// ZoneId.of("Asia/Calcutta")
LocalDate today = LocalDate.now(ZoneId.systemDefault());
System.out.println(dtfHindi.format(today));
System.out.println(dtfBangla.format(today));
System.out.println(dtfGerman.format(today));
System.out.println(dtfEnglish.format(today));
}
}
Output:
शुक्र
শুক্র
Fr.
Fri
Alternatively, starting with Java SE 8, you can use DayOfWeek#getDisplayName with the applicable Locale.
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
// Replace ZoneId.systemDefault() with the applicable timezone e.g.
// ZoneId.of("Asia/Calcutta")
LocalDate today = LocalDate.now(ZoneId.systemDefault());
System.out.println(today.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.forLanguageTag("hi")));
System.out.println(today.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.forLanguageTag("bn")));
System.out.println(today.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.forLanguageTag("de")));
System.out.println(today.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.forLanguageTag("en")));
}
}
Output:
शुक्र
শুক্র
Fr.
Fri
You can't do it with the Calendar class (unless you write your own), but you can with the Date class. (The two are usually used hand-in-hand).
Here's an example:
import java.util.Date;
public class DateFormatExample {
public static void main(String[] args) {
Calendar nowCal = Calendar.getInstance(); // a Calendar date
Date now = new Date(nowCal.getTimeInMillis()); // convert to Date
System.out.printf("localized month name: %tB/%TB\n", now, now);
System.out.printf("localized, abbreviated month: %tb/%Tb\n", now, now);
System.out.printf("localized day name: %tA/%TA\n", now, now);
System.out.printf("localized, abbreviated day: %ta/%Ta\n", now, now);
}
}
Output:
localized month name: June/JUNE
localized, abbreviated month: Jun/JUN
localized day name: Friday/FRIDAY
localized, abbreviated day: Fri/FRI
You can use this :
public String getDayString(){
Locale locale = Locale.getDefault();
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
return day.getDisplayName(TextStyle.FULL, locale);
}
The result will be: Monday
//you need to use joda library
List<String> dayList = new ArrayList<String>();
String[] days = new String[7];
int a=2;
//a =starting day of week 1=sunday ,2=monday
Calendar c2 = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
c2.set((Calendar.DAY_OF_WEEK),a);
int maxDay = c2.getActualMaximum(Calendar.DAY_OF_WEEK);
for(int i=0;i<maxDay;i++)
{
days[i] = df.format(c2.getTime());
c2.add(Calendar.DAY_OF_MONTH, 1);
String dayOfWeek = new LocalDate( days[i]).dayOfWeek().getAsShortText();
dayList.add(dayOfWeek);
}
for(int i=0;i<maxDay;i++)
{
System.out.print(" '"+dayList.get(i)+"'");
}