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);
Related
I'm developing an Android app that gets the date from the internet. What I have is a complete date format like this one : 2020-06-13T16:21:15.239920+02:00. I want to get the day of the month (which is 13 in this case).
If you are using at least API level 26, then you can use ZonedDateTime class as your string uses the default format that is understood by that class.
ZonedDateTime zdt = ZonedDateTime.parse("2020-06-13T16:21:15.239920+02:00");
int d = zdt.getDayOfMonth();
Alternatively, if the format is constant, simply use method substring()
String dd = "2020-06-13T16:21:15.239920+02:00".substring(8, 10);
If the format is not constant, I would suggest either regular expression or combining ZonedDateTime with DateTimeFormatter
Your date/time string complies with DateTimeFormatter.ISO_OFFSET_DATE_TIME. You can use java.time API to get the day of the month as shown below:
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String dateTimeStr = "2020-06-13T16:21:15.239920+02:00";
OffsetDateTime odt = OffsetDateTime.parse(dateTimeStr);
int day = odt.getDayOfMonth();
System.out.println(day);
}
}
Output:
13
If you can not use Java SE 8 Date and Time, check ThreeTenABP and also How to use ThreeTenABP in Android Project.
Its always a bad idea to split a string and extract data becuase the string will change to some other value once the date , month or any part of the date string changes and the string indexing will change
So use DateTimeFormatter
import java.time.MonthDay;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
public class SDF {
public static void main(String[] args) {
final TemporalAccessor parse = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx")
.parse("2020-06-13T16:21:15.239920+02:00");
int dayOfMonth = MonthDay.from(parse).getDayOfMonth();
System.out.println(dayOfMonth);
}
}
There should be a method getDayOfMonth() available on this variable
private int parseDate(ZonedDateTime date) {
int day = date.getDayOfMonth();
return day;
}
You can use String split. Just take this whole format of date and put it into String and then create a new String Array String[] array= str.split("[-T]"); and then you can get result from array[2].
String str = "2020-06-13T16:21:15.239920+02:00";
String[] array= str.split("[-T]");
System.out.println("OUTPUT: " + array[2]);
Output: 13
String str = "2020-06-13T16:21:15.239920+02:00";
String substr = "";
// prints the substring after index 7(8 includes) till index 9(10 excludes)
substr = str.substring(8, 10);
This question already has answers here:
Convert String Date to String date different format [duplicate]
(8 answers)
Changing String date format
(4 answers)
Parse String to Date with Different Format in Java
(10 answers)
How to format LocalDate to string?
(7 answers)
Closed 4 years ago.
I am looking for a solution that lets me turn a string containing an iso basic date format, such as 20190330 into a formatted date such as 2019-03-30 (Eur format) or 30/03/2019 (UK format) or 03/30/2019 (US format). The format depends on the format that the user selects.
The libraries java.time.LocalDate and java.time.format.DateTimeFormatter seem to offer possibilities of a solution but I find the documentation of these libraries incoherent and confusing and I’m not sure if a solution is possible from these sources.
I have tried the four solutions contained in the return statements shown in the code.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class DateFormatter {
private static final String EU_PATTERN = "yyyy-MM-dd";
private static final String UK_PATTERN= "dd/MM/yyyy";
private static final String US_PATTERN= "MM/dd/yyyy";
private static final int EU = 1;
private static final int UK = 2;
private static final int US = 3;
private static String formattedDate(int fmt, String isobasic){
String pattern = null;
switch(fmt) {
case EU: {pattern = EU_PATTERN; break;}
case UK: {pattern = UK_PATTERN; break;}
case US: {pattern = US_PATTERN; break;}
}
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
// return dateFormatter.format(isobasic); // String cannot be converted to Temporal Accessor
// return (String)dateFormatter.format(isobasic); // String cannot be converted to Temporal Accessor
// return LocalDate.parse(isobasic, dateFormatter); // LocalDate cannot be converted to String
return (String)LocalDate.parse(isobasic, dateFormatter); // LocalDate cannot be converted to String
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println(formattedDate(EU, "20180927"));
System.out.println(formattedDate(UK, "20190131"));
System.out.println(formattedDate(US, "20171225"));
}
The expected result would be three formatted dates according tp the format selected:
2018-09-27
31/01/2019
12/25/2017
The actual results are the syntax errors shown after the return codes following the case statement.
My workaround is to rewrite the case statement and use clumsy statements like the following (for the EU format):
case EU: { return isobasic.substring(0,4) + "-" + isobasic.substring(4,6) + "-" + isobasic.substring(6,8);}
If that’s the only solution I will live with that but I want to check out first of the formatter/localdate libraries offer a more elegant approach.
Following my comment, you should try using your iso format to get a TemporalAccessor from your String and then format it to the desired pattern.
I just made minimal changes in your code to achieve the result, you can try it
public class DateFormatter {
private static final String ISO = "yyyyMMdd";
private static final String EU_PATTERN = "yyyy-MM-dd";
private static final String UK_PATTERN = "dd/MM/yyyy";
private static final String US_PATTERN = "MM/dd/yyyy";
private static final int EU = 1;
private static final int UK = 2;
private static final int US = 3;
private static String formattedDate(int fmt, String isobasic) {
String pattern = null;
switch (fmt) {
case EU: {
pattern = EU_PATTERN;
break;
}
case UK: {
pattern = UK_PATTERN;
break;
}
case US: {
pattern = US_PATTERN;
break;
}
}
DateTimeFormatter parser = DateTimeFormatter.ofPattern(ISO);
TemporalAccessor parsedDate = parser.parse(isobasic);
return DateTimeFormatter.ofPattern(pattern).format(parsedDate);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println(formattedDate(EU, "20180927"));
System.out.println(formattedDate(UK, "20190131"));
System.out.println(formattedDate(US, "20171225"));
}
}
I have a string "2017-01-03T02:20:52+00:00" I want to convert into a LocalDateTime.
I tried the code below
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
public class HelloWorld{
public static void main(String []args){
System.out.println("Hello World");
String date = "2009-07-16T19:20:30-05:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime dateTime = LocalDateTime.parse(date, inputFormatter);
System.out.println(dateTime);
}
}
I tried various pattern but every time I am getting below error:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2009-07-16T19:20:30-05:00' could not be parsed at index 19
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at HelloWorld.main(HelloWorld.java:11)
A single Z does not allow : in the timezone. Use ZZZZZ (five Z) for the extended format.
The format of your date String is incorrect
Change it like so:
String date = "2009-07-16T19:20:30-0500";
Note the change before the timezone.
If you want to keep your date format, you can use this pattern:
String pattern = "yyyy-MM-dd'T'HH:mm:ssXXX";
try this:
String date = "2009-07-16T19:20:30-0500";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
or
String date = "2009-07-16T19:20:30-05:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssz";
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);
}
}
I have a string which can contain a date(yyyy-MM-dd) or date and time (yyyy-MM-dd HH:mm:ss) in respective formats.
I want to know which strings contains only date.
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(dateFormat.parse("2015-02-02"));
System.out.println(dateFormat.parse("2015-02-02 23:23:23"));
In above code, both the strings are parsed successfully, whereas the format is same for only first.
I would use the overload of parse which takes a ParsePosition - you can then check the position afterwards:
import java.util.*;
import java.text.*;
public class Test {
public static void main(String[] args) throws Exception {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
System.out.println(parseFully(dateFormat, "2015-02-02"));
System.out.println(parseFully(dateFormat, "2015-02-02 23:23:23"));
}
private static Date parseFully(DateFormat format, String text)
throws ParseException {
ParsePosition position = new ParsePosition(0);
Date date = format.parse(text, position);
if (position.getIndex() == text.length()) {
return date;
}
if (date == null) {
throw new ParseException("Date could not be parsed: " + text,
position.getErrorIndex());
}
throw new ParseException("Date was parsed incompletely: " + text,
position.getIndex());
}
}
public static void main(String[] args) {
String dateOnly = "2015-02-02";
String dateAndTimeOnly = "2015-02-02 23:23:23";
System.out.println("Date Only = " + validateDateFormat(dateOnly));
System.out.println("Date And time Only = " + validateDateFormat(dateAndTimeOnly));
}
public static boolean validateDateFormat(String input) {
return input.matches("([0-9]{4})-([0-9]{2})-([0-9]{2})");
}
output
Date Only = true
Date And time Only = false
Regex is self explanatory - Input will be separated by -, ist part([0-9]{4}) can contain 4 digit , 2nd part can contain 2 digit [0-9]{2}, so as 3rd.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
Let's first try to do it the way you have done:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String[] arr = { "2015-02-02", "2015-02-02 23:23:23" };
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.ENGLISH);
for (String s : arr) {
System.out.println("Attempting to parse '" + s + "':");
LocalDate date = LocalDate.parse(s, dtf);
System.out.println("Parsed successfully: " + date);
}
}
}
Output:
Attempting to parse '2015-02-02':
Parsed successfully: 2015-02-02
Attempting to parse '2015-02-02 23:23:23':
Exception in thread "main" java.time.format.DateTimeParseException: Text '2015-02-02 23:23:23' could not be parsed, unparsed text found at index 10
As you can see, the java.time API correctly throws an exception informing you about the problem. SimpleDateFormat, on the other hand, parses the input string silently which has caused the problem that you have posted.
Thus, with the modern date-time API, you have two easy options:
Simply catch the exception and say that the second input (i.e. 2015-02-02 23:23:23) is not a date string as per the specified date pattern.
Use the function, DateTimeFormatter#parse(CharSequence, ParsePosition) with the ParsePosition index set to 0.
Given below is a demo of the second option:
import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String[] arr = { "2015-02-02", "2015-02-02 23:23:23" };
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.ENGLISH);
for (String s : arr) {
ParsePosition pp = new ParsePosition(0);
LocalDate.from(dtf.parse(s, pp));
if (pp.getIndex() < s.length()) {
System.out.println("'" + s + "' is not a date string as per the specified date pattern.");
}
}
}
}
Output:
'2015-02-02 23:23:23' is not a date string as per the specified date pattern.
ONLINE DEMO
Note: Never use SimpleDateFormat or DateTimeFormatter without a Locale.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Once the desired format is reached , SimpleDateFormat doesnt format the rest of String . It is the reason why your second string is parsed.
This post SimpleDateFormat parse(string str) doesn't throw an exception when str = 2011/12/12aaaaaaaaa? may help you .
Also check the DateFormat#parse method in java docs