Calendar: how to get string “10:00 AM” - java

I’m trying to get a string like e.g. “10:00 AM”
int numberOfHourFrom_0_to_23=10;
Calendar m_auxCalendar = new GregorianCalendar();
m_auxCalendar.set(Calendar.HOUR, numberOfHourFrom_0_to_23 +12);//+12 makes it work correctly during PM hours, but not sure why.
m_auxCalendar.set(Calendar.MINUTE,0);
Date mdate=m_auxCalendar.getTime();
String mstring = DateFormat.getTimeInstance(DateFormat.SHORT).format(mdate);
If I use my Android phone during PM hours, this code works correctly (I get “10:00 AM”); however, if I use my phone during AM hours, I get “10:00 PM” instead of “10:00 AM”

java.time through desugaring
Consider using java.time, the modern Java date and time API, for your time work.
DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
int numberOfHourFrom0To23 = 10;
LocalTime time = LocalTime.of(numberOfHourFrom0To23, 0);
String mstring = time.format(timeFormatter);
System.out.println(mstring);
Output in US locale is (no surprises):
10:00 AM
A LocalTime is a time of day with no date, so seems to be all that you need here.
What went wrong in your code?
Unexpectedly Calendar.HOUR refers to hour within AM or PM, from 0 through 11. I never understood for what this is useful. When you create a GregorianCalendar in the morning and set its HOUR to 10, you get 10 AM. When you do the same in the afternoon, you get 10 PM. You tried to compensate by adding 12 hours. Now you set the hour to 22 even though the range was o through 11. Any decent class would throw an IllegalArgumentException (or similar). Not a Calendar object with default settings. Instead it adjusts the time to 10 AM on the next day. And now when you run your code in the morning, you get 10 PM, as you observed.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Related question: Difference between Calendar.HOUR and Calendar.HOUR_OF_DAY?
Documentation of Calendar.HOUR

I had solved it in a different way. Maybe, it helps you. But unfortunately, I couldn't try the code on Android...
Here is my code:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
// other code...
int numberOfHourFrom_0_to_23 = 15;
String hour = numberOfHourFrom_0_to_23 + ""; // you need a string for the following parsing
String mstring = "";
// you have to do it here, because in the other case you do it in the try block,
// you wouldn't have access on it after finishing it
try{
DateFormat hh = new SimpleDateFormat("hh");
// your input date format, in this case only hours
Date date = hh.parse(hour);
/* you have to parse the value of the string to a Date object,
can throw a 'ParseException' exception --> try-catch */
SimpleDateFormat targetFromat = new SimpleDateFormat("hh aa");
// your target format, 'aa' is for AM/PM
mstring = targetFromat.format(date);
// the method formats the time to the new format (incl. AM/PM)
} catch(ParseException e){
// exception threw by parse in the class Date
System.err.println("There was an error during parsing the initial string.");
e.printStackTrace();
}
System.out.println(mstring); // test output, in this case: 03 PM
Maybe is this article interesting for you: https://beginnersbook.com/2017/10/java-display-time-in-12-hour-format-with-ampm/ (it helped me by this answer).
UPDATE:
After reading the comment from #Ole V.V. (thank you for your correction!), I look at the class DateTimeFormatter and I want to add the code here (it is much simpler as my first code!):
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
// other code...
int numberOfHourFrom_0_to_23 = 15;
LocalTime time = LocalTime.of(numberOfHourFrom_0_to_23, 0, 0);
// parameters: hour, minute, second
String formatPattern = "hh a";
// the pattern, "hh" is for the two hours positions and "a" for AM/PM
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern);
String mstring = formatter.format(time);
// formatting the value and solve it as a String
System.out.println(mstring); // test output, in this case: 03 PM

Related

Java - Not the expected format from Locale

I'm having some issues in some countries, on this case is with the Locale("cs", "CZ") the format of the date I'm looking for is dd. MM. but is returning dd.MM., how can I solve this?
I'm trying to get the pattern doing this :
val pattern = DateFormat.getBestDateTimePattern(locale, "ddMM")
val dateFormatted = DateTimeFormatter.ofPattern(pattern,locale).withLocale(locale).format(date)
But the problem is since I'm using this Locale it's somehow assigned with an unexpected date formatter.
How can I get this dd. MM. pattern?
The code is in kotlin but i tag java so if you put a Java answer and it works I'll mark it as a correct one.
If you need a pattern for the complete date, DateTimeFormatter#ofLocalizedDate meets your requirement precisely. However, if you need to restrict it to just days and months, the options are limited. I have shown a couple of the options below:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Locale locale = new Locale("cs", "CZ");
DateTimeFormatter dtf1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).localizedBy(locale);
// Test
String formatted = dtf1.format(LocalDate.now());
System.out.println(formatted);
// If you are required to remove year, do it explicitly
formatted = formatted.replaceAll("\\s+\\d{4}", "");
System.out.println(formatted);
// Or use a fixed format
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("dd. MM.", locale);
// Test
System.out.println(dtf2.format(LocalDate.now()));
}
}
Output:
7. 10. 2021
7. 10.
07. 10.
ONLINE DEMO
Learn more about the modern Date-Time API* from Trail: Date Time.
* 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. Note that Android 8.0 Oreo already provides support for java.time.

java.util.Locale constructor does not workwhen using "gsw" as a Swiss language locale in Java 8

The context:
A customer asked me to help him with a method to format a Joda DateTime with a Locale specified as a parameter.
The problem:
Using "gsw" (Swiss German) as a language does not seem to have an effect on the translation (falls back to English in my case).
"gsw" is part of ISO639-2 (which is ISO639 alpha-3, which the Java locale says it supports, https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html).
I verified to be 100% sure and gsw is part of alpha-3, but it wasn't part of alpha-2 (ISO639-1): https://www.loc.gov/standards/iso639-2/php/English_list.php
I've tried with other languages which are part of alpha-3 but were not present in alpha-2 and I see the same strange behavior.
Have I might not read well enough the Locale helpcenter?
The code:
//all are types belong to joda.time, except Locale, which is java.util
DateTimeZone dtZone = DateTimeZone.forID(IANATimezone);
DateTime dtus = dateTime.withZone(dtZone);
Locale locale = new Locale(Language, Region);
DateTimeFormatter dtf = DateTimeFormat.fullDateTime().withLocale(locale);

Numeric date format

How to change date format from 14-feb-2019 to 14-02-2019 in android studio, actually I am picking my system date but I want to change Feb to month number in Android Studio, here is my code snippets:
eddate = (EditText) findViewById(R.id.editdate);
edtime = (EditText) findViewById(R.id.editime);
eddate.setFocusable(false);
Calendar calendar = Calendar.getInstance();
String currentDate = DateFormat.getDateInstance().format(calendar.getTime());
String[] arr=currentDate.split(" ");
String date=arr[0]+"-"+arr[1]+"-"+arr[2];
// Toast.makeText(this, ""+date, Toast.LENGTH_SHORT).show();
eddate.setText(date);
You are using the built-in date format for your locale, which is a good idea. It’s simple, you are exploiting that someone knows what that format looks like, and your code lends itself well to internationalization. When you do that, you can choose how long or short of a format you want. You probably did something equivalent to the following:
ZoneId zone = ZoneId.of("Asia/Karachi");
Locale pakistan = Locale.forLanguageTag("en-PK");
DateTimeFormatter mediumFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(pakistan);
LocalDate today = LocalDate.now(zone);
System.out.println(today.format(mediumFormatter));
15-Feb-2019
In my snippet I have specified a medium format. I think that your best bet is to use the short format instead:
DateTimeFormatter shortFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.SHORT).withLocale(pakistan);
System.out.println(today.format(shortFormatter));
15/02/2019
This uses slashes instead of hyphens. I would trust that this is how people in your culture generally will expect to see a date when written in a short format. And you’re saved of your string manipulation or other hand formatting.
In my snippets I am using java.time, the modern Java date and time API. Calendar and DateFormat are long outdated, the latter in particular notoriously troublesome. The modern API is so much nicer to work with.
Disclaimer: I have run the snippets on my Java 10. Output on Android may vary. I wouldn’t be too worried. In all cases the built-in localized formats have been chosen with care.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Try this will help you
public class Test {
public static void main(String[] args) {
String parseddate = parseDateToddMMyyyy("14-feb-2019");
System.out.println(parseddate);
}
public static String parseDateToddMMyyyy(String time) {
String outputPattern = "dd-MM-yyyy";
String inputPattern= "dd-MMM-yyyy";
SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern);
SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern);
Date date = null;
String str = null;
try {
date = inputFormat.parse(time);
str = outputFormat.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return str;
}
}
String dateFormat= "dd-MM-yyyy";
Date date = calendar.getTime();
String dateText= new SimpleDateFormat(dateFormat).format(date);

Custom date format in android for given locale

I'm trying to format a date for a given locale new Locale("mk", "MK"). The locale is valid, it returns the country name and language properly. I want to use custom string, in my case "E, kk:mm" or "EEEE, kk:mm". I want the output to be "сабота, 12:00", but what I get is "7, 12:00".
This is how I use it and I tried many ways, but they all seem to behave the same.
SimpleDateFormat sdf = new SimpleDateFormat("EEEE, kk:mm", new Locale("mk", "MK));
sdf.format(new Date());
// output: 7, 12:30
Another method I tried
Calendar calendar = Calendar.getInstance(new Locale("mk", "MK"));
calendar.setTimeInMillis(new Date().getTime());
DateFormat.format("EEEE, kk:mm", calendar);
// output: Saturday, 12:30
I also tried using java.text.DateFormat instead android class, but no change.
The phone locale is set to English, but this is localized app, I want to show dates in a fixed locale format.
I've looked into many SO question regarding this issue and I wasn't able to find answer. I'm not interested in predefined formats, I want to use my own format and I want the date/month names to be formatted for the input locale.
I think the problem is that Macedonia is not a supported locale on the Android JVM. If you run your code as plain Java console app, it's fine. The method Locale.getAvailableLocales() returns 152 members in plain Java, only 88 in an Android emulator. If you have the code snippet:
Locale[] locales = Locale.getAvailableLocales();
String cCode;
for (Locale loc :locales){
cCode = loc.getCountry();
if (cCode.equalsIgnoreCase("MK"))
Toast.makeText(this, cCode, Toast.LENGTH_SHORT).show();
// Or System.out.println() in a Java app
}
Then the toast doesn't show for "MK" although it will println in the Java app
From documentation of SimpleDateFormat:
**Text**: For formatting, if the number of pattern letters is 4 or more,
the full form is used; otherwise a short or abbreviated form is used if
available. For parsing, both forms are accepted, independent of the
number of pattern letters.
So this should fix it:
SimpleDateFormat sdf = new SimpleDateFormat("EEEE, kk:mm", new Locale("mk", "MK"));
NickT was faster :-), so just adding to his answer: if you want to see your locales supported on Android, run:
for (Locale l:Locale.getAvailableLocales()) {
Log.d(l.getDisplayCountry(),l.toString());
}
and you will see that Macedonia is not on the list.

Android Time Class format time

How do I format time using Android's Time Class.
I want to display time in this format "hh:mm AM/PM" . I have tried using the Time.format function but I'm not sure if I'm using it correctly.
Thanks
Please try this..
SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");
Date dt = new Date();
String strValue = timeFormat.format(dt);
Time time = new Time();
time.set(0, 0, 17, 4, 5, 1999);
Log.i("Time", time.format("%d.%m.%Y %H:%M:%S"));
try:
String strTime = time.format("%I:%M %p");
Your answer can be derived from, but not limited to this link, a C++ reference about "ctime":
http://www.cplusplus.com/reference/ctime/strftime/
I found this link to be very helpful deciphering the string formats used in my own work.
The Android.Text.Format.Time.Format docs assumes you know something:
Where or how to read "man" page for strftime, which if you weren't familiar using Linux (or a Mac at the terminal) might require some creative web searching or know what "See man strftime for what means what." referred to. Informal as it is in official documentation, it does build off and reference what has already has come before and is left as an exercise for the developer.

Categories

Resources