What's the time format of now() in Threeten? - android

I use ThreeTen module and when I print ZonedDateTime.now(), I get.
2019-07-11T22:43:36.564-07:00[America/Los_Angeles]
What's the format of this?
I tried uuuu-MM-dd'T'HH:mm:ss.SSS'Z' and It says,
org.threeten.bp.format.DateTimeParseException: Text '2019-07-11T22:43:36.564-07:00[America/Los_Angeles]' could not be parsed at index 23
So, after SSS, the 'Z' part is incorrect.
What's the proper way to implement it?
This is my code:
val pstTime = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")).toString()
val timeFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS'Z'")
val mTime = LocalDateTime.parse(pstTime, timeFormatter).toString()
tv_pstTime.text = mTime
I want to parse it to the format like Tuesday, July 2 5:15:01 P.M.
How can I do that?

You can use DateTimeFormatter.ofPattern("...."). Inside .ofPattern("....") you can have any pattern you want.
Like this:
val result = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"))
.format(DateTimeFormatter.ofPattern("EEEE, MMMM d HH:mm:ss a"))
Output: Thursday, July 11 23:51:21 PM

Related

How to format string to date in Android

In my application I one string such as 2023-2-14 and I want convert this to 2023-02-14.
I write below codes:
val format = SimpleDateFormat("yyyy-MM-dd")
val date: Date = format.parse(startDateStr)
Log.e("dateLog",""+date)
But in logcat show me this : Wed Feb 15 00:00:00 GMT+03:30 2023
Why? I used this format : yyyy-MM-dd.
Why not used this format?
you are just parsing date, without a time, thus date object have set 00 for hour, day etc. now use format method for converting old String to new one
val formatAs = "yyyy-MM-dd"
var format = SimpleDateFormat(formatAs)
val date: Date = format.parse(startDateStr)
Log.e("dateLog","date:"+date)
String dateAsStringFormatted = format.format(date);
Log.e("dateLog","dateAsStringFormatted:"+dateAsStringFormatted)
some other answers in HERE

Displaying time from timestamp in Unix, UTC in Android Kotlin

I am working on a simple weather app and am trying to display time in the format "K:mm a" (eg. 6:30 AM). I am fetching a timestamp in Unix, UTC for the specified place a user searches for such as NYC. The timestamp looks something like 1624836905 and the time zone offset such as -14400. I have a function which adds the two up, converts it to milliseconds and should return the time in the format specified. The function is as follows:
fun dateTime(time: Int, zone: Int, format: String = "EEE, MMMM d K:mm a"): String {
return try {
val sdf = SimpleDateFormat(format)
val netDate = Date((time.plus(zone)).toLong() * 1000)
sdf.timeZone = TimeZone.getTimeZone("UTC")
sdf.format(netDate)
} catch (e: Exception) {
e.toString()
}
}
And I call it such as:
sunriseTextView.text = dateTime(result2.lookup<Int>("daily.sunrise")[0], timeZone, "K:mm a")
sunsetTextView.text = dateTime(result2.lookup<Int>("current.sunset")[0], timeZone, "K:mm a")
The expected output is the sunrise/sunset time such as 6:01 AM and 9:05 PM. I am also rendering the current time at the specified place also obtained from the API. As follows:
dateView.text = dateTime(result2.lookup<Int>("current.dt")[0], timeZone)
Which outputs the current date and time at the place in the format "EEE, MMMM d K:mm a" (eg. Mon June 28 8:23 AM).
The current time is always correct, however, there is a problem with the sunrise and sunset times. If I input NYC, for example, the sunrise is 7:35 PM and sunset 10:39 AM. The sunrise and sunset for Tokyo, on the other hand, appears correct at 4:27 AM and 7:00 PM.
Clearly I am missing something as I know the API data is correct. I am looking for any suggestions, however, I would appreciate one which does not have API restrictions such as kotlinx-datetime which requires API 26.
Since there's API Desugaring, you can use java.time with API versions below 26.
That means you don't have to rely on those outdated datetime classes, like java.util.Date and java.text.SimpleDateFormat.
Your fun can be rewritten like this:
fun dateTime(time: Int, zone: String, format: String = "EEE, MMMM d K:mm a"): String {
// parse the time zone
val zoneId = ZoneId.of(zone)
// create a moment in time from the given timestamp (in seconds!)
val instant = Instant.ofEpochSecond(time.toLong())
// define a formatter using the given pattern and a Locale
val formatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH)
// then make the moment in time consider the zone and return the formatted String
return instant.atZone(zoneId).format(formatter)
}
Here's some example use in a simple fun main():
fun main() {
val timestamp: Int = 1624836905 // your example epoch seconds
// try two different zones
val newYorkTime = dateTime(timestamp, "America/New_York")
val tokyoTime = dateTime(timestamp, "Asia/Tokyo")
// and print the results
println(newYorkTime)
println(tokyoTime)
}
Output of this example:
Sun, June 27 7:35 PM
Mon, June 28 8:35 AM
Please note that you could as well use an offset: Int instead of a zone: String if you simply want to provide an offset of hours from UTC. You would need to adjust two lines of this fun then:
fun dateTime(time: Int, offset: Int, format: String = "EEE, MMMM d K:mm a"): String {
// parse the time zone
val zoneOffset = ZoneOffset.ofHours(offset)
// create a moment in time from the given timestamp (in seconds!)
val instant = Instant.ofEpochSecond(time.toLong())
// define a formatter using the given pattern and a Locale
val formatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH)
// then make the moment in time consider the zone and return the formatted String
return instant.atOffset(zoneOffset).format(formatter)
}
Using that in a main like this
fun main() {
val timestamp: Int = 1624836905
val newYorkTime = dateTime(timestamp, -4)
val tokyoTime = dateTime(timestamp, 9)
println(newYorkTime)
println(tokyoTime)
}
will produce the very same output.
In addition, the Locale used in the DateTimeFormatter could as well be a function argument in case you want to support different languages (this affects the names of months and days of week).
I have a similar function in Python like this:
def time(self, unix_time, time_zone):
date = datetime.utcfromtimestamp(unix_time + time_zone)
return (datetime.strftime(date, '%I:%M %p'))
Which I call as follows:
WeatherApp.time_zone = self.weather_results['timezone_offset']
print(self.time_date(self.weather_results['current']['dt'], self.time_zone))
print('Sunrise: ' + self.time(self.weather_results['current']['sunrise'], self.time_zone))
print('Sunset: ' + self.time(self.weather_results['current']['sunset'], self.time_zone))
I am trying to get the same result in Kotlin. However comparing the outputs is as follows:
Location: Tokyo, Japan
Current time and date: Tue, June 29 06:53 PM (same in Python and Kotlin from Asia/Tokyo, 1624960598 1624961970
32400)
Sunrise: 04:27 AM (as outputted in Python from 32400, 1624908462)
Sunset: 07:00 PM (as outputted in Python from 32400, 1624960847)
Sunrise: 4:27 AM (as outputted in Kotlin from Asia/Tokyo, 1624908467)
Sunset: 7:00 PM (as outputted in Kotlin from Asia/Tokyo, 1624960846)
---
Location: New York, United States
Current time and date: Tue, June 29 6:02 AM (same in Python and Kotlin from America/New_York, 1624960973)
Sunrise: 05:27 AM (as outputted in Python from -14400, 1624958860)
Sunset: 08:31 PM (as outputted in Python from -14400, 1625013070)
Sunrise: 7:35 PM (as outputted in Kotlin from America/New_York, 1624923330)
Sunset: 10:39 AM (as outputted in Kotlin from America/New_York, 1624977548)
Comparing the timestamps shows that the data obtained from the API differs for some reason. I currently solved it by using a different API. I was using the One Call API by OpenWeather. I can't think of a reason why this is happening, however, by getting the timestamp from a different API the issue no longer persists.

How to Convert "2021-05-14T13:42:48.000Z" string to Date Object?

I am trying to convert "2021-05-14T13:42:48.000Z" string to Date Object.
I have tried this:
DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DDHH:MM:SS");
And also this, which i saw on stackoverflow only:-
DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DD'T'HH:MM:SS'A'");
But none of it worked.
How can i convert this string to my date object?
Assuming your date string always represents a UTC time (with the 'Z'), you can use format string:
yyyy-MM-dd'T'HH:mm:ss.SSSZ
but you'll first need to replace the Z in your date string with the fixed timezone "+0000", as in "2021-05-14T13:42:48.000+0000".
Try this:
String myDateString = "2021-05-14T13:42:48.000Z"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
Date myDate = dateFormat.parse (myDateString.replace("Z","+0000"));
This will return a date correctly adjusted for your current timezone, in my case 9:42:48am EDT.
There is a more detailed discussion at Converting ISO 8601-compliant String to java.util.Date which you may find useful.
You have used the date-time format incorrectly. It's important to note that the date-time formats have different meanings between capitalized and small letters.
For example: Capital MM means months, whereas small mm means minutes.
To know more about the date formats, you can refer this:
https://cheatography.com/pezmat/cheat-sheets/date-time-formats/pdf/
or this:
https://devhints.io/datetime
And the answer for your case is:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Please do not use SimpleDateFormat or even java.date. All these classes are deprecated.
Instead, rely on the Android available java.time package.
In short:
val source = "2021-05-14T13:42:48.000Z"
val parsed = ZonedDateTime.parse(source)
This will correctly parse the timezone (Z for Zulu/UTC/GMT).
You can verify this, by simply converting the parsed Zoned date time into, for example, Europe/Amsterdam time (which is +2).
val source = "2021-05-14T13:42:48.000Z"
val parsed = ZonedDateTime.parse(source)
parsed.toString() // prints: 2021-05-14T13:42:48Z
parsed.zone // prints: "Z"
ZoneId.of(parsed.zone.id) // returns the ZoneOffset "Z" (correct)
// Convert to Amsterdam Time
val amsterdamDateTime = parsed.withZoneSameInstant(ZoneId.of("Europe/Amsterdam"))
amsterdamDateTime.toString() // prints: 2021-05-14T15:42:48+02:00[Europe/Amsterdam] (2 hours ahead of the Zulu time, also correct).
parsed.format(DateTimeFormatter.ISO_DATE_TIME).toString() // Prints: 2021-05-14T13:42:48Z (correct)
So as you can see, these classes do the right thing (most of the time).
I suggest you use them.

Kotlin convert DateTime to 10 digit TimeStamp

I'm trying to find out how I can convert DateTime to 10 digit timestamp in Kotlin (Android Studio), I can't find any equivalent of it in Kotlin.
For example:
I have a val with date-time value like :
val dateTime = "2020-12-13 17:54:00"
Now I want to convert it to 10 digit timestamp like "1607842496"
Please give me a simple sample to show how I can resolve this problem. Thanks in advance.
Use the SimpleDateFormat class to parse your date String to a Date object. You can then get the timestamp (in milliseconds) from that Date object like so:
val dateTime = "2020-12-13 17:54:00"
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val date = simpleDateFormat.parse(dateTime)
val timestamp = date?.time
Divide the timestamp by a 1000 to get the 10 digit (in seconds) timestamp.

ThreeTenABP not parsing date

I am trying to convert ISO 8601 time into something human readable and in the local timezone of the Android device.
String date = "2016-09-24T06:24:01Z";
LocalDate test = LocalDate.parse(date, ISO_INSTANT);
But it returns:
method threw 'org.threeten.bp.format.DateTimeParseException' exception
From reading http://www.threeten.org/threetenbp/apidocs/org/threeten/bp/format/DateTimeFormatter.html#ISO_INSTANT it seems like what I'm doing should be possible.
What am I doing wrong?
Edit
Expanded exception error:
Unable to obtain LocalDate from TemporalAccessor: DateTimeBuilder[fields={MilliOfSecond=0, NanoOfSecond=0, InstantSeconds=1474698241, MicroOfSecond=0}, ISO, null, null, null], type org.threeten.bp.format.DateTimeBuilder
Edit 2
The solution is in the answer below. For anyone that stumbles across this, if you want to specify a custom output format you can use:
String format = "MMMM dd, yyyy \'at\' HH:mm a";
String dateString = DateTimeFormatter.ofPattern(format).withZone(ZoneId.systemDefault()).format(instant);
#alex answer is correct. Here is a working example.
Instant represents a point in time. To convert to any other local types you will need timezone.
String date = "2016-09-24T06:24:01Z";
This date string is parsed using the DateTimeFormatter#ISO_INSTANT internally.
Instant instant = Instant.parse(date);
From here you can convert to other local types just using timezone ( defaulting to system time zone )
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
LocalTime localTime = instant.atZone(ZoneId.systemDefault()).toLocalTime();
Alternatively, you can use static method to get to local date time and then to local date and time.
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
You need to use Instant.parse().
This will give you an Instant that you can combine with a time zone to create a LocalDate.
In Kotlin:
Converts to LocalDateTime directly based on your local time zone::
val instant: Instant = Instant.parse("2020-04-21T02:22:04Z")
val localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime()
Converts to Date and time separately based on your local time zone:
val localDate: LocalDate = instant.atZone(ZoneId.systemDefault()).toLocalDate()
val localTime: LocalTime = instant.atZone(ZoneId.systemDefault()).toLocalTime()

Categories

Resources