I have method that can take 2 different types of date formats:
MM/YY (credit card expiration date)
yyyyMMdd (funding expiration date)
Credit card expiration date is considered expired on the last day of that month. So, if cc date is May, 2017 (05/17), this cc is considered expired on 31th of May.
Funding expiration date will expire on the day it says it expires. So, if I am looking at it on the same day, it should return TRUE as funding has expired.
This is my code:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public static boolean dateHasExpired(String dateInput)
{
LocalDate d = LocalDate.now();
LocalDate dateParsed = null;
if (dateInput.contains("/"))
{
int iYear = Integer.parseInt(dateInput.substring(dateInput.indexOf("/") + 1));
int iMonth = Integer.parseInt(dateInput.substring(0, dateInput.indexOf("/")));
int daysInMonth = LocalDate.of(iYear, iMonth, 1).getMonth().maxLength();
dateInput = iMonth+"/"+daysInMonth+"/"+iYear;
}
else
{
dateInput = ConvertDate(dateInput, "yyyyMMdd", "MM/dd/yyyy");
}
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
dateParsed = LocalDate.parse(dateInput, dateTimeFormatter);
return d.compareTo(dateParsed) <= 0;
}
public static String ConvertDate(String dateValue, String currentFormat, String requiredFormat)
{
SimpleDateFormat inFormatter = new SimpleDateFormat(currentFormat);
SimpleDateFormat outFormatter = new SimpleDateFormat(requiredFormat);
String outDate = "";
try
{
java.util.Date date = inFormatter.parse(dateValue);
outDate = outFormatter.format(date);
}
catch (ParseException e) {
ErrorLogger.logError ( e );
}
return outDate;
}
Does anyone know of better way of doing this?
I also noticed LocalDate doesn't account for Leap Year, so Feb 2015 has 29 days, just like Feb 2016, so my daysInMonth will not be a good number.
Looks like Date is more tollerant than LocalDate when it comes to year being yy and month 5 for month of May.
You can use java.time.YearMonth class, which contains a method that returns the last day of the respective month (and also takes care of leap years):
public static boolean dateHasExpired(String dateInput) {
LocalDate today = LocalDate.now();
LocalDate dateParsed = null;
if (dateInput.contains("/")) {
// parse credit card expiration date
YearMonth ym = YearMonth.parse(dateInput, DateTimeFormatter.ofPattern("MM/yy"));
// get last day of month (taking care of leap years)
dateParsed = ym.atEndOfMonth();
} else {
// parse funding expiration date
dateParsed = LocalDate.parse(dateInput, DateTimeFormatter.ofPattern("yyyyMMdd"));
}
// expired if today is equals or after dateParsed
return ! today.isBefore(dateParsed);
}
With this code (considering that today is May 02, 2017):
System.out.println(dateHasExpired("04/17")); // true
System.out.println(dateHasExpired("05/17")); // false
System.out.println(dateHasExpired("06/17")); // false
System.out.println(dateHasExpired("20170501")); //true
System.out.println(dateHasExpired("20170502")); // true
System.out.println(dateHasExpired("20170503")); // false
Note that atEndOfMonth() method takes care of leap years, so these will also work:
System.out.println(dateHasExpired("02/15"));
System.out.println(dateHasExpired("02/16"));
I've added a System.out.println(dateParsed); in dateHasExpired method, just to check if the date is being parsed correctly. And the output for the dates above are (respectively):
2015-02-28
2016-02-29
And dateHasExpired returns true for both, as expected.
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
Is there an easy/direct way to use a DateTimeFormatter pattern to get the next LocalDateTime time that matches that pattern?
I'd like to use this to easily get the next time that an event should happen (could be daily, weekly, monthly, etc.). For example, if an event happens at "Monday 12:00 AM", I would like to get a LocalDateTime for the next Monday at 12:00 AM.
/**Get next LocalDateTime that matches this input
*
* #param input a String for time matching the pattern: [dayOfWeek ][dayOfMonth ][month ][year ]<timeOfDay> <AM/PM>
* #return LocalDateTime representing the next time that matches the input*/
public LocalDateTime getNextTime(String input) {
LocalDateTime currentTime = LocalDateTime.now();
DateTimeFormatter format = DateTimeFormatter.ofPattern("[eeee ][d ][MMMM ][u ]h:m a");
TemporalAccessor accessor = format.parse(input);
// TODO somehow get the next time (that's after currentTime) that matches this pattern
// LocalDateTime time = ???
return time;
}
I can't just do LocalDateTime.from(accessor) because there might not be a year, month, or day of month specified in the input.
To clarify, here are some examples of what I would like:
// if current date is Friday, January 1st, 2021 at 12:00 PM
// this should return a LocalDateTime for Monday, January 4th, 2021 12:00 AM
getNextTime("Monday 12:00 AM");
// should return Saturday, January 2nd, 2021 12:00 AM
getNextTime("12:00 AM");
// should return Tuesday, January 5th, 2021 12:00 AM
getNextTime("5 January 12:00 AM");
// should return Friday, January 8th, 2021 12:00 PM (must be AFTER current time)
getNextTime("Friday 12:00 PM");
No, there is neither an easy nor a direct way to do what you are asking for. It involves quite a bit of coding. You basically have got 16 cases because each of year, month, day of month and day of week may or may not be present. And you more or less will have to handle each case separately.
Also there may not be such a next time. If the year is 2019 there isn’t. If the string is Friday 12 January 2021 2:00 AM, there isn’t because 12 January is a Tuesday, not a Friday.
private static DateTimeFormatter format = DateTimeFormatter
.ofPattern("[eeee ][uuuu ][d ][MMMM ][uuuu ]h:m a", Locale.ENGLISH);
// input = [dayOfWeek] [dayOfMonth] [month] [year] <timeOfDay> <AM/PM>
public static LocalDateTime next(String text) {
TemporalAccessor accessor;
try {
accessor = format.parse(text);
} catch (DateTimeParseException dtpe) {
return null;
}
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
LocalTime parsedTime = LocalTime.from(accessor);
LocalDate earliest = now.toLocalDate();
if (parsedTime.isBefore(now.toLocalTime())) {
earliest = earliest.plusDays(1);
}
return resolveYearMonthDomDow(earliest, accessor).atTime(parsedTime);
}
private static LocalDate resolveYearMonthDomDow(LocalDate earliest, TemporalAccessor accessor) {
if (accessor.isSupported(ChronoField.YEAR)) {
Year parsedYear = Year.from(accessor);
if (parsedYear.isBefore(Year.from(earliest))) {
return null;
}
return resolveMonthDomDow(parsedYear, earliest, accessor);
} else {
Year candidateYear = Year.from(earliest);
while (true) {
LocalDate resolved = resolveMonthDomDow(candidateYear, earliest, accessor);
if (resolved != null) {
return resolved;
}
candidateYear = candidateYear.plusYears(1);
}
}
}
private static LocalDate resolveMonthDomDow(Year year, LocalDate earliest, TemporalAccessor accessor) {
if (accessor.isSupported(ChronoField.MONTH_OF_YEAR)) {
YearMonth knownYm = year.atMonth(accessor.get(ChronoField.MONTH_OF_YEAR));
if (knownYm.isBefore(YearMonth.from(earliest))) {
return null;
}
return resolveDomDow(knownYm, earliest, accessor);
} else {
YearMonth candidateYearMonth = YearMonth.from(earliest);
if (candidateYearMonth.getYear() < year.getValue()) {
candidateYearMonth = year.atMonth(Month.JANUARY);
}
while (candidateYearMonth.getYear() == year.getValue()) {
LocalDate resolved = resolveDomDow(candidateYearMonth, earliest, accessor);
if (resolved != null) {
return resolved;
}
candidateYearMonth = candidateYearMonth.plusMonths(1);
}
return null;
}
}
private static LocalDate resolveDomDow(YearMonth ym, LocalDate earliest, TemporalAccessor accessor) {
if (accessor.isSupported(ChronoField.DAY_OF_MONTH)) {
int dayOfMonth = accessor.get(ChronoField.DAY_OF_MONTH);
if (dayOfMonth > ym.lengthOfMonth()) {
return null;
}
LocalDate resolved = ym.atDay(dayOfMonth);
if (resolved.isBefore(earliest)) {
return null;
} else {
return resolveDow(resolved, accessor);
}
} else {
LocalDate candidateDate = earliest;
if (YearMonth.from(earliest).isBefore(ym)) {
candidateDate = ym.atDay(1);
}
while (YearMonth.from(candidateDate).equals(ym)) {
LocalDate resolved = resolveDow(candidateDate, accessor);
if (resolved != null) {
return resolved;
}
candidateDate = candidateDate.plusDays(1);
}
return null;
}
}
private static LocalDate resolveDow(LocalDate date, TemporalAccessor accessor) {
if (accessor.isSupported(ChronoField.DAY_OF_WEEK)) {
if (date.getDayOfWeek().getValue() == accessor.get(ChronoField.DAY_OF_WEEK)) {
return date;
} else {
return null;
}
} else {
return date;
}
}
Let’s try it out:
String input = "Monday 12:00 AM";
// get the next time that matches this pattern
LocalDateTime time = next(input);
System.out.println(time);
Output when I ran just now (Monday Januar 11, 2021 in the evening):
2021-01-18T00:00
So next Monday. Looks right.
For a different example, showing that leap years are respected:
String input = "Wednesday 29 February 12:00 AM";
2040-02-29T00:00
There are most probably bugs in my code, but the basic idea is working.
The time of day poses no problem. The challenge is with the date. I am using the time of day to determine whether today’s date is an earliest candidate. If the time now is already past the time in the string, the earliest possible date is tomorrow. For your example string, Monday 12:00 AM, this will practically always be the case: it is always after 12 midnight.
You had got an ambiguity in Monday 25 12:00 AM since 25 may be a year (a couple of millennia ago) or a day of month. I solved it by insisting on a four digit year. So if a number in the beginning or right after a day of week has four digits, it’s a year, otherwise it’s a day of month. The formatter I use looks funny, the year comes twice. I needed this to force the parsing to try year before trying day of month, or it would sometimes have taken a four digit number to be day of month. This in turn means that the formatter accepts a few formats too many. I figure it won’t be a problem in practice.
Provided your input is well formatted and is always in English, you could split your input at the first space and use it as follows:
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
public class Example {
public static void main(String[] args) {
LocalDateTime desiredDay = getNextDayTime("Friday 12:00 AM");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd.MM.yyyy hh:mm a");
System.out.println(dtf.format(desiredDay));
}
public static LocalDateTime getNextDayTime(String input){
String[] splited = input.split(" ", 2);
LocalTime localTime = LocalTime.parse(splited[1], DateTimeFormatter.ofPattern("hh:mm a", Locale.US));
LocalDateTime dateTime = LocalDateTime.now().with(localTime);
LocalDateTime desiredDay = dateTime.with(TemporalAdjusters.next(DayOfWeek.valueOf(splited[0].toUpperCase())));
return desiredDay;
}
}
input list
from date ex) 2020-10-01
to date ex) 2020-10-30
List [day of week] ex) [sun,mon....]
List [week] ex) [1,4,5]
I would like to know how to get a specific day of the week between the two dates.
Thank.
from date ex) 2020-10-01 to date ex) 2020-10-30
Your input string is already in the ISO8601 format for date and therefore it can be parsed without providing a DateTimeFormatter explicitly. In order to get the output string in a custom format (e.g. yyyy-MM-dd), you need to format the date object using DateTimeFormatter.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String inputStrDate = "2020-10-01";
LocalDate date = LocalDate.parse(inputStrDate);
String outputStrDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(outputStrDate);
}
}
Output:
2020-10-01
However, if your input is some other format, you will need to use DateTimeFormatter in order to parse it to a date object.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Formatter for input string
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy");
String inputStrDate = "10-01-2020";
LocalDate date = LocalDate.parse(inputStrDate, inputFormat);
// Formatter for output string
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String outputStrDate = date.format(outputFormat);
System.out.println(outputStrDate);
}
}
Output:
2020-10-01
Learn more about date-time API from Trail: Date Time.
for(LocalDate d = fromDate; !d.isAfter(toDate); d = d.plusDays(1)) { // 일정 시작 ~ 끝 loop
for (Integer wf : weekOfMonth) {
for (Integer df : dayOfWeek) {
offDay = d.with(fieldWeek, wf)
.with(fieldDay, df);
if (d.getMonth() == offDay.getMonth() && !offDays.contains(offDay)) {
offDays.add(offDay);
}
}
}
}
Sorry for asking the wrong question.
And thank you very much.
I've already made it, but I've studied your code.
java.time
I too recommend that you use java.time, the modern Java date and time API, for your date work. My shot is:
LocalDate fromDate = LocalDate.of(2020, Month.OCTOBER, 1);
LocalDate toDate = LocalDate.of(2020, Month.OCTOBER, 30);
List<DayOfWeek> daysOfWeek = List.of(DayOfWeek.SUNDAY, DayOfWeek.MONDAY);
List<Integer> weeks = List.of(1, 4, 5);
if (! YearMonth.from(fromDate).equals(YearMonth.from(toDate))) {
throw new IllegalStateException("Covering more than one month is not yet supported");
}
WeekFields wf = WeekFields.SUNDAY_START;
for (int week : weeks) {
for (DayOfWeek dow : daysOfWeek) {
LocalDate date = fromDate.with(wf.weekOfMonth(), week)
.with(wf.dayOfWeek(), dow.get(wf.dayOfWeek()));
// Is date inside interval?
if (! (date.isBefore(fromDate) || date.isAfter(toDate))) {
System.out.println(date);
}
}
}
Output:
2020-10-18
2020-10-19
2020-10-25
2020-10-26
The dates printed are Sunday and Monday of weeks 4 and 5 of October defining weeks in the American way where the week begins on Sunday (since you mentioned Sunday first in your example list) and week 1 is the week of October 1. Sunday and Monday of week 1 are not printed because they fall before October 1, that is, in September.
Consider which week scheme you require. You may use for example WeekFields.ISO or WeekFields.of(Locale.getDefault()).
I am finding the week first, then the day of week, because to me this is the natural way. I need to use the WeekFields object for both adjustments to make sure that the chosen week scheme is respected.
If you need to cover more than one calendar month, iterate over the months and do the same for each. Also check that the result date falls within the month so duplicates near month borders are ignored.
I tried looking at this link for inspiration: Parsing a date’s ordinal indicator ( st, nd, rd, th ) in a date-time string
However I am getting an error when I try to parse a string "Mon 21st May" to "Monday 21st May" - full day name, date number and full month.
Exception in thread "main" java.time.format.DateTimeParseException:
Text 'Mon 21st May' could not be parsed at index 0 at
java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at
java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDate.parse(LocalDate.java:400) at
HelloWorld.main(HelloWorld.java:45)
Here is the code:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
// one class needs to have a main() method
public class HelloWorld
{
// arguments are passed using the text field below this editor
public static void main(String[] args) throws Exception
{
String str = "Mon 21st May";
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
LocalDate datetext = LocalDate.parse(str, parseFormatter);
}
}
UPDATE:
Here is the latest code I have tried following suggestions and I changed the string to see if the issue is with that and below is there error I now receive. Looks like it knows the dates, just not able to parse it:
public static void main(String[] args) throws Exception
{
String str = "Tue 21st May";
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
LocalDate datetext = LocalDate.parse(str, parseFormatter);
}
}
Error:
Exception in thread "main" java.time.format.DateTimeParseException:
Text 'Tue 21st May' could not be parsed: Unable to obtain LocalDate from
TemporalAccessor: {DayOfWeek=2, DayOfMonth=21, MonthOfYear=5},ISO of
type java.time.format.Parsed at
java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at
java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.LocalDate.parse(LocalDate.java:400) at
HelloWorld.main(HelloWorld.java:26) Caused by:
java.time.DateTimeException: Unable to obtain LocalDate from
TemporalAccessor: {DayOfWeek=2, DayOfMonth=21, MonthOfYear=5},ISO of
type java.time.format.Parsed at
java.time.LocalDate.from(LocalDate.java:368) at
java.time.format.Parsed.query(Parsed.java:226) at
java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 2 more
MonthDay
If you want to parse month and day of month without a year, use MonthDay:
String str = "Mon 21st May";
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
MonthDay md = MonthDay.parse(str, parseFormatter);
System.out.println(md);
Output is:
--05-21
The leading dash indicates an absent year. EEEE in the format pattern string is for full name of the day of week, like Monday or Tuesday. For the abbreviation you need either E, EE or EEE.
LocalDate
If you want a LocalDate, you need to supply a year somehow. One option is:
LocalDate datetext = md.atYear(Year.now(ZoneId.of("Europe/London")).getValue());
System.out.println(datetext);
2019-05-21
This doesn’t validate the day of month, though. To do that:
String str = "Tue 21st May";
DateTimeFormatter parseFormatter = new DateTimeFormatterBuilder()
.appendPattern("EEE d['st']['nd']['rd']['th'] MMMM")
.parseDefaulting(ChronoField.YEAR, Year.now(ZoneId.of("Europe/London")).getValue())
.toFormatter(Locale.ENGLISH);
LocalDate datetext = LocalDate.parse(str, parseFormatter);
2019-05-21
In the comment you asked:
What about if I want to output it as Tuesday 21 May?
It’s sort of a new question and has been covered many times, but OK.
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("EEEE d MMMM", Locale.ENGLISH);
System.out.println(datetext.format(outputFormatter));
Tuesday 21 May
Detecting year from day of week
I may not know the year, as in I am trying to view dates in an
application but some dates may be this year, some may fall over to
next year but these dates don't have a year supplied
The following complete example assumes the date falls within the next 3 years from today and detects the year where the day of week is correct. On success it prints in your desired format.
String str = "Wed 20th May";
ZoneId zone = ZoneId.of("Europe/London");
LocalDate today = LocalDate.now(zone);
int currentYear = today.getYear();
LocalDate datetext = null;
final int maxYearsFromToday = 3;
for (int year = currentYear; year <= currentYear + maxYearsFromToday; year++) {
DateTimeFormatter parseFormatter = new DateTimeFormatterBuilder()
.appendPattern("EEE d['st']['nd']['rd']['th'] MMMM")
.parseDefaulting(ChronoField.YEAR, year)
.toFormatter(Locale.ENGLISH);
try {
datetext = LocalDate.parse(str, parseFormatter);
System.out.println("Day of week matched for year " + year);
break;
} catch (DateTimeParseException dtpe) {
// Ignore, try next year
}
}
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("EEEE d MMMM", Locale.ENGLISH);
if (datetext == null) {
System.out.println("Could not parse date;"
+ " possibly the day of week didn’t match for any year in the range "
+ currentYear + " through " + (currentYear + maxYearsFromToday));
} else if (datetext.isBefore(today) || datetext.isAfter(today.plusYears(maxYearsFromToday))) {
System.out.println("Date is out of range");
} else {
System.out.println("Successfully parsed: " + datetext.format(outputFormatter));
}
Day of week matched for year 2020
Successfully parsed: Wednesday 20 May
It's Tuesday 21st May 2019. The code below works.
String str = "Tue 21st May 2019";
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM yyyy", Locale.ENGLISH);
LocalDate datetext = LocalDate.parse(str, parseFormatter);
Here is my code to search for correct year:
Without knowing the day-name of the week, you have a 6/7 chance of parsing the date into the incorrect year. BUT, if you know the day-name, then you can search a 7 year range to find the correct year.
Assuming you have either a date like one of the following:
Wednesday, May 27
WED 5/27
And formatters like:
DateTimeFormatter visibleButtonFormat = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE M/dd")
.toFormatter(Locale.US);
DateTimeFormatter accessibleFormat = DateTimeFormatter.ofPattern("EEEE, MMMM dd");
Then, you can parse a MonthDay like so:
MonthDay monthDay = MonthDay.parse(dateText, oneOfTheAboveFormatters);
Then, you can search for the correct year. In this case it is 2020:
private static int findYearMatchingMonthDay(String dateText, MonthDay monthDay) {
for(int checkYear = 2020; checkYear >= 2016; checkYear--) {
LocalDate localDate = LocalDate.of(checkYear, monthDay.getMonth(), monthDay.getDayOfMonth());
String shortDay = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US).toUpperCase();
if (shortDay.equals(dateText.substring(0,3))) {
ConsoleUtils.logDebug("Assuming schedule buttons within year: " + checkYear);
return checkYear;
}
}
return Year.now().getValue();
}
I have two dates
1) from_date: eg. 01/01/2010 (1st January 2010)
2) present_date: eg. 05/06/2011 (5th June 2011)
I want the third date as:
3) req_date: eg. 01/01/2011(1st January 2011)
Year should come from "present_date" and day and month should come from "from_date".
The dates which I mentioned are hardCoded.
In my code, I run a query to get these 2 dates.
Look into the Calendar class
http://www.java-examples.com/add-or-substract-days-current-date-using-java-calendar
Something like // Untested
Calendar cal=Calendar.getInstance();
cal.setTime(from_date);
Calendar cal2=Calendar.getInstance();
cal2.setTime(present_date);
Calendar cal3=Calendar.getInstance();
cal3.set(cal2.get(CALENDAR.YEAR),cal1.get(CALENDAR.MONTH),cal1.get(CALENDAR.DATE));
Date reg_date = cal3.getTime();
You can set individual fields of dates:
Date req_date = from_date;
req_date.setYear (present_date.getYear());
Or, if you're using Calendar (Date is deprecated):
Calendar req_date = from_date;
req_date.set (YEAR, present_date.get(YEAR));
If they're strings, you can just use substringing to get what you want:
String req_date = from_date.substring(0,6) + present_date.substring(6);
(assuming XX/XX/YYYY as seems to be the case).
Not sure if I understand you correctly but this example should get you started:
int year = 2003;
int month = 12;
int day = 12;
String date = year + "/" + month + "/" + day;
java.util.Date utilDate = null;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
utilDate = formatter.parse(date);
System.out.println("utilDate:" + utilDate);
} catch (ParseException e) {
System.out.println(e.toString());
e.printStackTrace();
}
this way you can convert date Strings to java.util.Date object, then you can construct the third date by using Date/Calendar methods
from_date: for EX. 01/01/2010 (1 st January 2010)
present_date :for EX. 05/06/2011(5th june 2011)
String s1[]=from_date.split("/");
String s2[]=present_date.split("/");
String newDate=s1[0]+"/"+s1[1]+"/"+s2[2];
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
Date date = new Date();
System.out.println(date.toString());
}
}