String input of weekdays in German to Localdate - java

I have a string input of weekdays in German and need to get the next Localdate after today which corresponds to the given weekday string. If for example the input is Montag (Monday) I need the output as Localdate of 2022-05-16 which is the next Monday after today. If the input was in english I could do something like:
String input = "Monday";
LocalDate today = LocalDate.now();
LocalDate nextWeekday = today.with(TemporalAdjusters.next(DayOfWeek.valueOf(input.toUpperCase())));
System.out.println(nextWeekday);
Is there something I can do, may be using Locale, to use strings (days) given in German to get the next weekday as a Localdate? If possible without defining my own Enum? I would want to avoid doing
public enum DayOfWeekGerman {
MONTAG,
DIENSTAG,
MITTWOCH,
...
//methods & getters
}
and map them somehow to use the java.time API methods like Localdate.with...

The classes of java.time are data classes. They do not have a locale. They happen to be English names only because the Java language itself is in English.
However, you can make a Map for looking up a DayOfWeek value from a name:
private static final Map<String, DayOfWeek> germanDaysOfWeek =
Arrays.stream(DayOfWeek.values()).collect(
Collectors.toMap(
d -> d.getDisplayName(TextStyle.FULL, Locale.GERMAN), d -> d));
{Freitag=FRIDAY, Samstag=SATURDAY, Montag=MONDAY, Mittwoch=WEDNESDAY, Donnerstag=THURSDAY, Dienstag=TUESDAY, Sonntag=SUNDAY}
Perform a lookup on that map.
String input = "Montag";
LocalDate today = LocalDate.now();
LocalDate nextWeekday = today.with(
TemporalAdjusters.next(germanDaysOfWeek.get(input)));
See all this code run live at Ideone.com.
2022-05-16

Considering today is 09/May/2022 (Monday), you can try :
String input = "Montag";
LocalDate today = LocalDate.now();
DayOfWeek weekday = DayOfWeek.from(
DateTimeFormatter.ofPattern("EEEE", Locale.GERMAN).parse(input));
LocalDate nextWeekday = today.with(TemporalAdjusters.next(weekday));
System.out.println(nextWeekday);
Output:
2022-05-16
If you execute it on any other day, you might get different output based on day & date.

Related

Format date from String to LocalDate

I have a problem parsing a String to LocalDate.
According to similar questions on Stackoverflow and documentation I am using the correct values ​​dd (day of the month), MM (month of the year) and yyyy (year).
My String
String mydate = "18.10.2022 07:50:18";
My parsing test code
System.out.println(
LocalDate.parse(testPasswordExp)
.format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")
)
);
Error:
Caused by: java.lang.RuntimeException:
java.time.format.DateTimeParseException:
Text '18.10.2022 07:50:18' could not be parsed at index 0
The main problem of your code example is that you first parse the String to a LocalDate without the use of a suitable DateTimeFormatter and then format() it with a DateTimeFormatter that tries to format hour of day, minute of hour and second of minute which just aren't there in a LocalDate.
You can parse this String to a LocalDate directly, but better parse it to a LocalDateTime because your String contains more than just information about
day of month
month of year
year
Your myDate (and probably the testPasswordExp, too) has a time of day. You can get a LocalDate as the final result that way, too, because a LocalDateTime can be narrowed down toLocalDate().
A possible way:
public static void main(String[] args) {
// example datetime
String testPasswordExp = "18.10.2022 07:50:18";
System.out.println(
LocalDateTime // use a LocalDateTime and…
.parse( // … parse …
testPasswordExp, // … the datetime using a specific formatter,
DateTimeFormatter.ofPattern("dd.MM.uuuu HH:mm:ss")
).toLocalDate() // then extract the LocalDate
);
}
Output:
2022-10-18
You don't use the specified format for parsing, you use it to format the parsed date.
LocalDate.parse(mydate)
… uses the default ISO_LOCAL_DATE format. You are looking for this overload:
LocalDate.parse(mydate, DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"))
This method uses the specified format for parsing string to date. See this code run at Ideone.com.
Note that you are using LocalDate, meaning it will throw away the time part, keeping only the date after parsing. You probably meant to use LocalDateTime.
You can use
String mydate = "18.10.2022 07:50:18";
LocalDate ld = LocalDate.parse(mydate, DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
System.out.println(ld.toString());

Date object from DAY, MONTH, YEAR

I am trying to create a method which converts DAY, MONTH, YEAR to Date object in Java
I have
String DAY = "31"
String YEAR = "2012"
String MONTH = "11"
I need a configurable Format as output.
String format = "MM/dd/yyy";
I will always get DAY string from "01" to "31" only
I will always get YEAR string from "1000" to "9999" only
I will always get MONTH string from "01" to "12" only (Never get Jan, Feb etc)
I understand that SimpleDateFormat(format) can work up to some extend.
new SimpleDateFormat("MM/dd/yyyy") will parse "02/01/2010" as Feb 01 2010 but
new SimpleDateFormat("mm/dd/yyyy") will parse "02/01/2010" as Jan 01 2010
Is it possible to write a generic method in java which converts given Strings (DAY, MONTH, YEAR) to Date object based on a configurable pattern?? and which can throw exception is I supply a wrong combination of DAY, MONTH, YEAR (like DAY = "31", MONTH = "02", YEAR = "2010")
Something like :
Date dateParser(String format){
String DAY = "01";
String YEAR = "1922";
String MONTH = "02";
return date;
}
There are basically two ways:
Parse each string to a number and put the numbers together to a date.
Put the strings together to one string and parse it into a date.
Some middle forms are thinkable, but I recommend you take a pure stance and use one of the ways only. The answer by Arvind Kumar Avinash shows option 1. My taste is rather for option 2., so let me demonstrate.
I recommend you use java.time, the modern Java date and time API for your date work.
String format = "MM/dd/yyy";
String day = "31";
String year = "2012";
String month = "11";
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format, Locale.US);
String isoDateString = year + '-' + month + '-' + day;
LocalDate date = LocalDate.parse(isoDateString);
String formattedDate = date.format(dateFormatter);
System.out.println(formattedDate);
Since there are only 30 days in November (month 11), this code very sensibly throws an exception:
Exception in thread "main" java.time.format.DateTimeParseException:
Text '2012-11-31' could not be parsed: Invalid date 'NOVEMBER 31'
That is, we have got input validation for free. For a valid date the code will parse the date and format as requested.
Link
Oracle tutorial: Date Time explaining how to use java.time.
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to 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.
Note that mm is used for minute; not for month. For month, you use MM. Check this for more information.
Using the modern date-time API:
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getLocalDate("2010", "02", "28"));
System.out.println(getLocalDate("2010", "02", "31"));
}
static LocalDate getLocalDate(String year, String month, String dayOfMonth) {
return LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(dayOfMonth));
}
}
Output:
2010-02-28
Exception in thread "main" java.time.DateTimeException: Invalid date 'FEBRUARY 31'
at java.base/java.time.LocalDate.create(LocalDate.java:459)
at java.base/java.time.LocalDate.of(LocalDate.java:271)
at Main.getLocalDate(Main.java:11)
at Main.main(Main.java:7)
Note that a date-time object is supposed to store the information about date, time, time-zone etc. but not about the formatting. When you print an object of a date-time type, its is supposed to print what its toString method returns. If you need to print the date-time in a different format, you need a formatting class (e.g. DateTimeFormatter) which can return you a string in your desired pattern e.g.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getFormattedLocalDate("2010/02/28", "yyyy/MM/dd", "EEEE dd MMMM yyyy"));
System.out.println(getFormattedLocalDate("28/02/2010", "dd/MM/yyyy", "yyyy MMM EEE dd"));
}
static String getFormattedLocalDate(String date, String inputPattern, String outputPattern) {
return LocalDate.parse(date, DateTimeFormatter.ofPattern(inputPattern))
.format(DateTimeFormatter.ofPattern(outputPattern));
}
}
Output:
Sunday 28 February 2010
2010 Feb Sun 28

Fetching only month from the date and giving month name in java

I have fetched the date month and year from the text file so now i want to fetch only month part and I have to get month name I have done like this
String s;
String keyword = "Facture du";
while ((s = br.readLine()) != null) {
if (s.contains(keyword)) {
// s= s.replaceAll("\\D+","");
System.out.println(s);
}
}
Actual Output: Facture du 28/05/2018
Expected Output: only Month name
Using java-8's LocalDate you can just do :
String strDate = "28/05/2018";
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate localDate = LocalDate.parse(strDate, format);
System.out.println(localDate.getMonth());
which gives the output as MAY
Nicholas K already provided an answer nicely showing the use of java.time. I just wanted to add that java.time can do a bit more than shown there.
DateTimeFormatter factureLineFormatter
= DateTimeFormatter.ofPattern("'Facture du' dd/MM/uuuu");
String keyword = "Facture du";
String s = "Facture du 28/05/2018";
if (s.contains(keyword)) {
LocalDate date = LocalDate.parse(s, factureLineFormatter);
Month month = date.getMonth(); // Extract a `Month` enum object.
String output =
month.getDisplayName( // Get localized name of month.
TextStyle.FULL, // How long or abbreviated should the month name be.
Locale.FRENCH) // `Locale` determines the human language used in translation, and the cultural norms used in abbreviation, punctuation, and capitalization.
;
System.out.println(output);
}
Output:
mai
I am parsing the entire line immediately by adding the literal text in quotes in the format pattern string. I am printing the localized month name — here in French, but you can choose another language. You may also choose to have it abbreviated if you prefer.
Edit: Basil Bourque has kindly edited my code spelling out in comments what each method and argument does. This makes the code look long, but is great for the explanation in a Stack Overflow answer. In production code you would probably use a one-liner:
System.out.println(date.getMonth().getDisplayName(TextStyle.FULL, Locale.FRENCH));
You could use Calendar from the java.utils package:
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date date = format.parse("28/05/2018");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
System.out.println(cal.getDisplayName(Calendar.MONTH, Calendar.LONG_FORMAT, Locale.FRENCH));
I'm assuming you speak french and want to display the french name. Otherwise you will need to adjust the Locale parameter.
For your date this code will output "mai".

How to convert date as string from 17-Dec-2018 to 2018-12-17 in java. I want to store it to MYSQL database

I have successfully imported date column from excel to the java code. However, I am unable to change the date format from 17-Dec-2018 to 2018-12-17. Kindly help.
public void saveToDatabase(Vector dataHolder) throws ParseException {
System.out.println(dataHolder);
for(Iterator iterator = dataHolder.iterator();iterator.hasNext();) {
List list = (List) iterator.next();
fullName = list.get(0).toString();
idNumberString = list.get(1).toString();
//idNumber = Integer.parseInt ( idNumberString );
committee = list.get(2).toString();
amountString = list.get(3).toString();
//amount = Integer.parseInt ( amountString );
bosaFosa = list.get(4).toString();
purpose = list.get(5).toString();
paymentsType = list.get(6).toString();
supportingDocuments = list.get(7).toString();
entryDate = list.get(8).toString();
}
The code now after fetching data from excel column the month is in text as "Dec" that is "17-Dec-2018"
I expect the final output in string as "2018-12-17" so that I can store in MYSQL database as DATE Type.
java.time
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d-MMM-uuuu", Locale.ENGLISH);
String fullName = "Emmanuel Macron";
int idNumber = 42;
String entryDateString = "17-Dec-2018";
LocalDate entryDate = LocalDate.parse(entryDateString, dateFormatter);
PreparedStatement insertStatement = yourDbConnection.prepareStatement(
"insert into your_table (name, id, entry) values (?, ?, ?);");
insertStatement.setString(1, fullName);
insertStatement.setInt(2, idNumber);
insertStatement.setObject(3, entryDate);
int rowsInserted = insertStatement.executeUpdate();
The example is a bit simpler than yours, but should answer what you are asking about, so I trust the rest to you. I am using (and warmly recommending) java.time, the modern Java date and time API, for all date work in Java.
The steps involved for the date are:
Parse the date string into a LocalDate. LocalDate.parse(entryDateString, dateFormatter) does this. In the format pattern string, d-MMM-uuuu d means day of month in 1 or 2 digits, MMM means month abbreviation, and uuuu means 4 digit year. The month abbreviation is locale specific. Since I took Dec to be English, I have specified English locale for the formatter; please correct if your date strings are in some other language.
Pass the LocalDate to your PreparedStatement. insertStatement.setObject(3, entryDate); does this.
If you want to check that the first point worked as expected:
System.out.println("Entry date was parsed into " + entryDate);
Output:
Entry date was parsed into 2018-12-17
PS You may also want to check whether you can get the date from Excel in a different way. If you are using an older library such as Apache POI, I am afraid that the other option is an old-fashioned Date object, which you would then need to convert, so it’s a question whether it’s worth it.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Your code is just simple. Here is code:
Parse string input.
String fromDate="17-Dec-2018";
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(fromDate, dateFormatter);
Generate string output.
String convertedDate = localDate.toString();
System.out.println(convertedDate);
Here DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.ENGLISH) is the input date format and locale.
Here is the imports:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
EDIT:
Please follow the answer of #Ole V.V. given above as it is a better solution than mine.
You will first have to convert the String data into Date object.
Example code:
String sDate1="31/12/1998";
Date date1=new SimpleDateFormat("dd/MM/yyyy").parse(sDate1);
Then you can use SimpleDateFormat class to format date as you wish.
For more details on SimpleDateFormatter class, check this out

Java 8 timezone conversion

I know there are similar questions like this, but I wasn't quite able to find the example similar to mine. I learned about LocalDateTime and ZonedDateTime but I don't know how to tell my ZonedDateTime what's assumed timezone of parsed date.
I'm migrating from Java 7 to Java 8. In my code, I have a method like this:
public String changeTZ(String tzFrom, String tzTo, String dateToChange) {
ZoneId zoneFrom = ZoneId.of(tzFrom);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat.toPattern());
LocalDateTime localtDateAndTime = LocalDateTime.parse(dateToChange, formatter);
ZonedDateTime dateAndTimeINeed = ZonedDateTime.of(localtDateAndTime, zoneFrom );
ZonedDateTime rezDate = dateAndTimeINeed.withZoneSameInstant(ZoneId.of(tzTo));
return formatter.format(rezDate);
}
Example usage is:
String rez = changeTZ("CEST", "UTC", "2017-08-10 14:23:58");
As you can see it receives datetime in form of string, timezone date is in tzFrom variable and TZ I need (toTo variable).
Code which does that in Java 7 is absurd and complex so I won't enlist it here. Can you please tell me how to achieve the same in Java 8 without changing method interface (arguments and return type)? What about DST? Is it handled automatically in Java 8?
Note that method also supports timezones in form of "CEST", "CET", "UTC" as well as standard ones like "Europe/London".
Java 8 uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin).
Avoid using the short abbreviations (like CEST or PST) because they are ambiguous and not standard.
Actually, those names don't work with ZoneId mainly because of this ambiguity (CST, for example, can be "Central Standard Time", "Cuba Standard Time" or "China Standard Time"). Actually, some of them might work due to retro-compatibility reasons, but it's not guaranteed to work with all of them.
I'm assuming that CEST is the Central European Summer Time. There are lots of different countries (and timezones) that are currently in CEST, so the API can't decide which timezone to choose if you just pass "CEST" to it.
That's because a timezone contains all the different offsets a region had during its history. There may be lots of countries using CEST today, but their history differs in the past (some might had DST in different years, or used a different offset and then changed, etc), and that's why they have one timezone for each.
To use such short names (like CEST), though, you can define some defaults for each one (which will be an arbitrary choice) and put these choices in a map:
// map of custom zone names
Map<String, String> map = new HashMap<>();
// setting my arbitrary choices for each name
map.put("CEST", "Europe/Berlin"); // Berlin during DST period
map.put("CET", "Europe/Berlin"); // Berlin during non-DST period
// ... and so on
Then you can use this map to create the ZoneId:
// use the custom map to create the ZoneId
ZoneId zoneFrom = ZoneId.of(tzFrom, map);
...
// use the custom map to create the ZoneId
ZonedDateTime rezDate = dateAndTimeINeed.withZoneSameInstant(ZoneId.of(tzTo, map));
I've chosen Europe/Berlin, but of course you can change it to whatever timezone you need. You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
Using the map above:
System.out.println(changeTZ("CEST", "UTC", "2017-08-10 14:23:58"));
This code outputs:
2017-08-10 12:23:58
Note that 14:23 in CEST (which I chose to be Europe/Berlin) is 12:23 in UTC, which is correct because in August Berlin is in DST (offset is +02:00).
ZoneId and ZonedDateTime classes handle DST effects automatically. You can check this by choosing a date in January (when DST is not in effect in Berlin):
// January is not DST, so use CET
System.out.println(changeTZ("CET", "UTC", "2017-01-10 14:23:58"));
The output is:
2017-01-10 13:23:58
In January Berlin is not in DST, so the offset is +01:00, then 14:23 in Berlin becomes 13:23 in UTC.
Of course the ideal is to always use the full names (like Europe/Berlin), but the custom map is an alternative if you don't have control over the inputs.
Java 8 also has a built-in predefined map, but as any other predefined stuff, the choices are arbitrary and not necessarily the ones you need.
This solution uses the IANA timezones names mentioned by Hugo in the comments to get the ZoneId (more details here). Will throw an exception if you use it with CEST.
public static String changeTZ(String tzFrom, String tzTo, String dateToChange){
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of(tzFrom));
ZonedDateTime zdt = ZonedDateTime.parse(dateToChange, dtf);
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of(tzTo));
return zdt.format(dtf2);
}
Use like:
String rez = changeTZ("US/Alaska", "Europe/Berlin", "2017-08-10 14:23:58");
Here is a class that does the job.
public class TimeZoneConverter {
private static String datePattern = "yyyy-MM-dd HH:mm:ss";
public static void main(String[] args) throws ParseException {
String sourceDate = "2017-02-27 16:00:00";
String resultDate = convertTimeZone("EET", "UTC", sourceDate);
System.out.println("EET: "+ sourceDate);
System.out.println("UTC: "+ resultDate);
}
public static String convertTimeZone(String timeZoneFrom, String timeZoneTo, String date) throws ParseException {
long timestamp = stringToTimestamp(date, timeZoneFrom);
String result = timestampToString(timestamp, timeZoneTo);
return result;
}
public static long stringToTimestamp(String time, String timeZone) throws ParseException {
DateFormat format = getDateFormat(timeZone);
return format.parse(time).getTime();
}
public static String timestampToString(long timestamp, String timeZone) {
DateFormat format = getDateFormat(timeZone);
return format.format(new Date(timestamp));
}
private static DateFormat getDateFormat(String timeZone) {
DateFormat format = new SimpleDateFormat(datePattern);
format.setTimeZone(TimeZone.getTimeZone(timeZone));
return format;
}
}

Categories

Resources