From cc01bd18b2f522352b53ee4c4b1c7bcbb9c41994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20LUDWIG?= Date: Thu, 29 Jun 2023 23:03:03 +0200 Subject: [PATCH] feat(skill/date_time): time zone --- skills/utilities/date_time/config/en.json | 16 +++++ .../current_date_time_with_time_zone.ts | 69 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 skills/utilities/date_time/src/actions/current_date_time_with_time_zone.ts diff --git a/skills/utilities/date_time/config/en.json b/skills/utilities/date_time/config/en.json index b7328c32..6b37da37 100644 --- a/skills/utilities/date_time/config/en.json +++ b/skills/utilities/date_time/config/en.json @@ -48,12 +48,25 @@ "In how many days will it be February 10th?", "Calculate the number until March 1st" ] + }, + "current_date_time_with_time_zone": { + "type": "logic", + "utterance_samples": [ + "What is the time in San Francisco?", + "What time is it in Paris?", + "Can you tell me the current time in London?", + "What's the time right now in Tokyo?", + "What is the current date and time in New York City?" + ] } }, "answers": { "current_date_time": [ "It is %weekday%, %month% %day%, %year%, and it is %hours%:%minutes%:%seconds%." ], + "current_date_time_with_time_zone": [ + "Greetings from %city%, %country%! The local date and time is %weekday%, %month% %day%, %year%, and it is %hours%:%minutes%:%seconds%." + ], "current_date": ["It is %weekday%, %month% %day%, %year%."], "current_time": ["It is %hours%:%minutes%:%seconds%."], "current_week_number": ["It is the %week_number% week of the year."], @@ -62,6 +75,9 @@ ], "days_countdown_error": [ "I'm sorry, I didn't understand the date you said." + ], + "city_not_found": [ + "I'm sorry, I couldn't find the city you said. Please try again." ] } } diff --git a/skills/utilities/date_time/src/actions/current_date_time_with_time_zone.ts b/skills/utilities/date_time/src/actions/current_date_time_with_time_zone.ts new file mode 100644 index 00000000..c4e0389b --- /dev/null +++ b/skills/utilities/date_time/src/actions/current_date_time_with_time_zone.ts @@ -0,0 +1,69 @@ +import type { ActionFunction, SpacyLocationCityEntity } from '@sdk/types' +import { leon } from '@sdk/leon' + +import { zeroPad } from '../lib/zeroPad' + +/** + * Determine if the given date is in Daylight Saving Time (DST). + * @example isDaylightSavingTime(new Date(2020, 0, 1)) // false + * @example isDaylightSavingTime(new Date(2020, 7, 1)) // true + */ +function isDaylightSavingTime(date: Date): boolean { + const january = new Date(date.getFullYear(), 0, 1).getTimezoneOffset() + const july = new Date(date.getFullYear(), 6, 1).getTimezoneOffset() + return Math.max(january, july) !== date.getTimezoneOffset() +} + +/** + * Get the current date in Coordinated Universal Time (UTC). + */ +function getCurrentCoordinatedUniversalTime(): Date { + const currentDate = new Date() + const utcOffset = currentDate.getTimezoneOffset() + currentDate.setMinutes(currentDate.getMinutes() + utcOffset) + return currentDate +} + +export const run: ActionFunction = async function (params) { + let cityEntity: SpacyLocationCityEntity | null = null + for (const entity of params.current_entities) { + if (entity.type === 'location:city') { + cityEntity = entity + break + } + } + + if (cityEntity == null) { + return await leon.answer({ + key: 'city_not_found' + }) + } + + const { time_zone } = cityEntity.resolution.data + + const currentDate = getCurrentCoordinatedUniversalTime() + if (isDaylightSavingTime(currentDate)) { + currentDate.setHours( + currentDate.getHours() + time_zone.daylight_saving_time_offset + ) + } else { + currentDate.setHours( + currentDate.getHours() + time_zone.coordinated_universal_time_offset + ) + } + + await leon.answer({ + key: 'current_date_time_with_time_zone', + data: { + weekday: currentDate.toLocaleString(params.lang, { weekday: 'long' }), + month: currentDate.toLocaleString(params.lang, { month: 'long' }), + day: currentDate.getDate(), + year: currentDate.getFullYear(), + hours: zeroPad(currentDate.getHours()), + minutes: zeroPad(currentDate.getMinutes()), + seconds: zeroPad(currentDate.getSeconds()), + city: cityEntity.resolution.data.name, + country: time_zone.country_code + } + }) +}