js-joda convert UTC zoned datetime into local datetime - js-joda

I'm struggling to convert between a parsed UTC datetime into a LocalDateTime (America/New_York), with the hours adjusted accordingly between the two timezones, using the js-joda library.
In the javascript native Date object, what's stored is in UTC and is adjusted for the local (system) timezone at the time of display (.toString(), etc). I understand js-joda works differently, so I am assuming it's my own misunderstanding of just how js-joda timezones work. Regardless, I can't seem to get any kind of DateTime to report/show that it's 8am in the morning in New York, given a UTC time of 12pm noon.
Below is the Jest test-code to show what's been attempted so far.
import {
DateTimeParseException,
LocalDateTime,
ZonedDateTime, ZoneId,
} from '#js-joda/core';
import '#js-joda/timezone';
// (Jest tests)
test('converting a utc zoned-datetime into a local datetime', () => {
expect(ZoneId.systemDefault().id().toString()).toMatch('America/New_York');
// America/New_York is currently -04:00 from UTC (daylight savings on)
const utcStr1 = "2022-09-27T12:00:00Z";
const utcStr2 = "2022-09-27T12:00:00+00:00";
const utcDT = ZonedDateTime.parse(utcStr1);
// make sure I understand how parsing UTC forms work:
expect(utcDT).toEqual(ZonedDateTime.parse(utcStr2)); // OK
expect(utcDT.zone().id()).toEqual(ZoneId.UTC.id()); // OK
// trying to parse a UTC datetime string using LocalDateTime fails,
// so that won't work...
expect(() => LocalDateTime.parse("2022-09-27T12:00:00Z")).toThrow(DateTimeParseException);
expect(() => LocalDateTime.parse("2022-09-27T12:00:00+00:00")).toThrow(DateTimeParseException);
/*
How do I convert this UTC datetime into a LocalDateTime, adjusting for UTC (hr:12) -> America/New_York (hr:8)?
All of the below attempts fail, returning 12.
*/
expect(utcDT.toOffsetDateTime().hour()).toEqual(8); // FAILS: .hour() returns 12 not 8
expect(utcDT.toLocalDateTime().hour()).toEqual(8); // FAILS: .hour() returns 12 not 8
expect(utcDT.withZoneSameLocal(ZoneId.systemDefault()).hour()).toEqual(8); // FAILS: .hour() returns 12 not 8
});

The function to use is withZoneSameInstant:
const localDateTime = utcDT.withZoneSameInstant(ZoneId.systemDefault());

Related

convert LocalDateTime to Date by using kotlin

I have a java.time.LocalDateTime and i want to convert it in java.util.Date
val myLocalDateTime = LocalDateTime.now().plusDays(5)
I want to convert LocalDateTime.now().plusDays(5) to java.util.Date in kotlin.
How Can i do it?
You need to add mandatory information in order to make a LocalDateTime convertable to a java.util.Date…
Before you try, think about if you can use Instant.now(), because the methods for legacy compatibility require Instants as arguments:
fun main() {
// get "now" as Instant
val now = Instant.now()
// print the java.util.Date created from the Instant
println(Date.from(now))
// use the Instant plus 5 days to create another date
val date = Date.from(now.plus(5, ChronoUnit.DAYS))
// create a formatter for the Date
val formatter = SimpleDateFormat("yyyy-MM-dd")
// and print it using the formatter
println(formatter.format(date))
}
Output (some moments ago on my middle-european machine):
Thu Feb 09 15:31:06 CET 2023
2023-02-14
If you really need to use a LocalDateTime, which has no zone or offset, you will have to add one, convert the result (a ZonedDateTime or an OffsetDateTime) toInstant() and create Dates from those…
If it's all about dates (year, month of year, day of month) without time of day, you could simply use a java.time.LocalDate:
fun main() {
// get "today" as LocalDate
val today = LocalDate.now()
// print it using toString() implicitly
println(today)
// add five days
val fiveDaysLater = today.plusDays(5)
// and print it formatted by a prebuilt formatter
println(fiveDaysLater.format(DateTimeFormatter.ISO_LOCAL_DATE))
}
Output:
2023-02-10
2023-02-15

How do I return the local time portion of a string given a date string

I am wanting to display in a react native app a date given by the API.
The API is returning the following value:
"2022-06-20T14:00:00.000"
I need to display to the user
2:00 PM
The problem is that when I try this:
const dateString = "2022-06-20T14:00:00.000"
const date = new Date(dateString);
console.log(date)
The date has been changed to:
2022-06-20T14:00:00.000Z
Meaning it is 2pm UTC time when it should be 2pm local time.
On the end of the new Date variable, if you add the .toLocaleTimeString(), it should then output as 2:00:00PM.
const date = new Date(dateString).toLocaleTimeString();
you can use moment library with its localized formats,
here is the documentation for more of its formats https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/
const dateString = "2022-06-20T14:00:00.000"
console.log(moment(dateString).format('LT'))

Format vue-datepicker time in yyyy-mm-dd

I am using vue3-datepicker library.
<datepicker
v-model="to_date"
inputFormat="yyyy-MM-dd"
/>
My data method is below:
data(){
to_date: new Date(),
}
When I am selecting a date and printing {{this.to_date}}, it is printing in Fri Sep 17 2021 09:39:49 GMT+0530 (India Standard Time).
I want it in yyyy-MM-dd format.
How can I achieve this?
A quick solution is to use Date.prototype.toISOString(), which formats the date as:
yyyy-MM-ddTHH:mm:ss.sssZ
So you get the desired date format by splitting the result by T, and taking the first array element:
const formatDate = date => {
const tzOffset = date.getTimezoneOffset() * 60 * 1000
return new Date(date - tzOffset).toISOString().split('T')[0]
}
Then use the method in your template:
<span>{{ formatDate(to_date) }}</span>
demo
You can achieve using moment npm package
install:-
npm i moment
example:-
moment(new Date()).format("yyyy-MM-dd")
you can use Use different format
var dt = new Date();
console.log(moment(dt).format("YYYY-MM-DD HH:mm:ss"));
console.log("Date: "+moment(dt).format("YYYY-MM-DD"));
console.log("Year: "+moment(dt).format("YYYY"));
console.log("Month: "+moment(dt).format("MM"));
console.log("Month: "+moment(dt).format("MMMM"));

Kotlin SimpleDateFormat parse wrong timezone

My mobile timezone was GMT+7, I have a code to convert a specific date time(GMT+0) to a specific timezone(GMT+3):
var strDate = "2020-07-10 04:00:00+0000"
var result: Date?
var dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ")
dateFormatter.timeZone = TimeZone.getTimeZone("Asia/Jerusalem")
result = dateFormatter.parse(strDate)
The problem is result always return "Fri Jul 10 11:00:00 GMT+07:00 2020"
But I expected it will return date object "Fri Jul 10 07:00:00 GMT+03:00 2020", any idea what's wrong with my code?
It's recommended to use java.time and stop using java.util.Date, java.util.Calendar along with java.text.SimpleDateFormat because of problems like this one.
In your code, the target time zone is obviously not applied to the date but it isn't obvious why it isn't.
A different problem might be pattern you are using because your example String does not contain any unit of time smaller than seconds but the pattern tries to consider .SSS (which made the code fail in the Kotlin Playground).
Switch to java.time and handle this with modern classes, such as OffsetDateTime for parsing this String (it doesn't contain information about a specific time zone, just an offset of zero hours) and ZonedDateTime as the target object (this considers a real time zone which may have different offsets depending things like Daylight Saving Time).
You could do it like this:
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
fun main() {
// this example is in UTC (+0000 --> no offset / offset of 0 hours)
var strDate = "2020-07-10 04:00:00+0000"
// create a formatter that can parse Strings of this pattern
// ([] represents optional units to be parsed)
var dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss[.SSS]Z")
// and parse the String to an OffsetDateTime using this formatter
var resultOfParsing = OffsetDateTime.parse(strDate, dateFormatter)
// then print the parsed result
println(resultOfParsing)
// create the target time zone
var timeZone = ZoneId.of("Asia/Jerusalem")
// then use the target zone for a zone shift
var jerusalemTime: ZonedDateTime = resultOfParsing.atZoneSameInstant(timeZone)
// and print the result
println(jerusalemTime)
// you could use your formatter defined above for a differently formatted output, too
println(jerusalemTime.format(dateFormatter))
}
which outputs (including all intermediate results):
2020-07-10T04:00Z
2020-07-10T07:00+03:00[Asia/Jerusalem]
2020-07-10 07:00:00.000+0300

Unit test a date function

I need to create a unit test for the following function:
export default date => {
const dateInMs = new Date(date).getTime(); // UTC date
const clientDate = new Date();
// timezone offset is in minutes therefore it is being converted to milliseconds
const offset = clientDate.getTimezoneOffset() * 60 * 1000;
return new Date(dateInMs - offset).toISOString();
};
I know I should pass the test a date in the following format
2017-07-01T00:00:00+00:00
Can someone provide some guidance as to how to write a simple test with this information.