Skip to content

Commit 2c0b3ef

Browse files
authored
Infer the zone datetime in FFI when possible (#6517)
1 parent 04a64b6 commit 2c0b3ef

File tree

5 files changed

+63
-25
lines changed

5 files changed

+63
-25
lines changed

components/datetime/src/format/input.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,26 @@ impl DateTimeInputUnchecked {
6767
/// responsible for making sure the calendar matches the formatter.
6868
pub fn set_date_fields_unchecked<C: Calendar, A: AsCalendar<Calendar = C>>(
6969
&mut self,
70-
input: Date<A>,
70+
date_in_calendar: Date<A>,
7171
) {
72-
self.year = Some(input.year());
73-
self.month = Some(input.month());
74-
self.day_of_month = Some(input.day_of_month());
75-
self.iso_weekday = Some(input.day_of_week());
76-
self.day_of_year = Some(input.day_of_year());
72+
self.year = Some(date_in_calendar.year());
73+
self.month = Some(date_in_calendar.month());
74+
self.day_of_month = Some(date_in_calendar.day_of_month());
75+
self.iso_weekday = Some(date_in_calendar.day_of_week());
76+
self.day_of_year = Some(date_in_calendar.day_of_year());
7777
}
7878

7979
/// Sets all fields from a [`Time`] input.
80-
pub fn set_time_fields(&mut self, input: Time) {
81-
self.hour = Some(input.hour);
82-
self.minute = Some(input.minute);
83-
self.second = Some(input.second);
84-
self.subsecond = Some(input.subsecond);
80+
pub fn set_time_fields(&mut self, time: Time) {
81+
self.hour = Some(time.hour);
82+
self.minute = Some(time.minute);
83+
self.second = Some(time.second);
84+
self.subsecond = Some(time.subsecond);
8585
}
8686

8787
/// Sets the time zone UTC offset.
88-
pub fn set_time_zone_utc_offset(&mut self, offset: UtcOffset) {
89-
self.zone_offset = Some(offset);
88+
pub fn set_time_zone_utc_offset(&mut self, utc_offset: UtcOffset) {
89+
self.zone_offset = Some(utc_offset);
9090
}
9191

9292
/// Sets the time zone ID.

ffi/capi/src/zoned_date_formatter.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,8 @@ pub mod ffi {
517517
write: &mut diplomat_runtime::DiplomatWrite,
518518
) -> Result<(), DateTimeWriteError> {
519519
let mut input = icu_datetime::DateTimeInputUnchecked::default();
520-
let date = date.0.to_calendar(self.0.calendar());
521-
input.set_date_fields_unchecked(date); // calendar conversion on previous line
520+
let date_in_calendar = date.0.to_calendar(self.0.calendar());
521+
input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
522522
input.set_time_zone_id(zone.id);
523523
if let Some(offset) = zone.offset {
524524
input.set_time_zone_utc_offset(offset);
@@ -1009,8 +1009,8 @@ pub mod ffi {
10091009
write: &mut diplomat_runtime::DiplomatWrite,
10101010
) -> Result<(), DateTimeWriteError> {
10111011
let mut input = icu_datetime::DateTimeInputUnchecked::default();
1012-
let date = date.0.to_calendar(Gregorian);
1013-
input.set_date_fields_unchecked(date); // calendar conversion on previous line
1012+
let date_in_calendar = date.0.to_calendar(Gregorian);
1013+
input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
10141014
input.set_time_zone_id(zone.id);
10151015
if let Some(offset) = zone.offset {
10161016
input.set_time_zone_utc_offset(offset);

ffi/capi/src/zoned_date_time_formatter.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,8 @@ pub mod ffi {
518518
write: &mut diplomat_runtime::DiplomatWrite,
519519
) -> Result<(), DateTimeWriteError> {
520520
let mut input = icu_datetime::DateTimeInputUnchecked::default();
521-
let date = date.0.to_calendar(self.0.calendar());
522-
input.set_date_fields_unchecked(date); // calendar conversion on previous line
521+
let date_in_calendar = date.0.to_calendar(self.0.calendar());
522+
input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
523523
input.set_time_fields(time.0);
524524
input.set_time_zone_id(zone.id);
525525
if let Some(offset) = zone.offset {
@@ -528,6 +528,12 @@ pub mod ffi {
528528
if let Some(zone_name_timestamp) = zone.zone_name_timestamp {
529529
input.set_time_zone_name_timestamp(zone_name_timestamp);
530530
}
531+
else {
532+
input.set_time_zone_name_timestamp(icu_time::zone::ZoneNameTimestamp::from_date_time_iso(&icu_time::DateTime {
533+
date: date.0,
534+
time: time.0
535+
}))
536+
}
531537
if let Some(variant) = zone.variant {
532538
input.set_time_zone_variant(variant);
533539
}
@@ -1012,8 +1018,8 @@ pub mod ffi {
10121018
write: &mut diplomat_runtime::DiplomatWrite,
10131019
) -> Result<(), DateTimeWriteError> {
10141020
let mut input = icu_datetime::DateTimeInputUnchecked::default();
1015-
let date = date.0.to_calendar(Gregorian);
1016-
input.set_date_fields_unchecked(date); // calendar conversion on previous line
1021+
let date_in_calendar = date.0.to_calendar(Gregorian);
1022+
input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
10171023
input.set_time_fields(time.0);
10181024
input.set_time_zone_id(zone.id);
10191025
if let Some(offset) = zone.offset {
@@ -1022,6 +1028,12 @@ pub mod ffi {
10221028
if let Some(zone_name_timestamp) = zone.zone_name_timestamp {
10231029
input.set_time_zone_name_timestamp(zone_name_timestamp);
10241030
}
1031+
else {
1032+
input.set_time_zone_name_timestamp(icu_time::zone::ZoneNameTimestamp::from_date_time_iso(&icu_time::DateTime {
1033+
date: date.0,
1034+
time: time.0
1035+
}))
1036+
}
10251037
if let Some(variant) = zone.variant {
10261038
input.set_time_zone_variant(variant);
10271039
}

ffi/dart/test/icu_test.dart

+19-1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ void main() {
9595
VariantOffsetsCalculator(),
9696
);
9797

98+
final utcOffset = UtcOffset.fromSeconds(-420);
99+
final customZDT = ZonedIsoDateTime.fromEpochMillisecondsAndUtcOffset(
100+
1746140981731,
101+
utcOffset,
102+
);
103+
final customZone = TimeZoneInfo(
104+
TimeZone.fromBcp47('uslax'),
105+
offset: utcOffset,
106+
);
107+
98108
var locale = Locale.fromString('de-u-ca-islamic-umalqura');
99109

100110
///// DateFormatter /////
@@ -233,7 +243,7 @@ void main() {
233243
);
234244

235245
expect(
236-
() => ZonedDateTimeFormatter.genericLong(
246+
() => ZonedDateTimeFormatter.specificLong(
237247
locale,
238248
DateTimeFormatter.ymdet(locale),
239249
).formatIso(
@@ -268,6 +278,14 @@ void main() {
268278
'15.07.46 AH, 14:32:12 MEZ',
269279
);
270280

281+
expect(
282+
ZonedDateTimeFormatter.genericLong(
283+
locale,
284+
DateTimeFormatter.mdt(locale),
285+
).formatIso(customZDT.date, customZDT.time, customZone),
286+
'03.11., 23:02:41 Nordamerikanische Westküstenzeit',
287+
);
288+
271289
///// ZonedDateTimeFormatterGregorian /////
272290
273291
expect(

tools/make/codegen/templates/zoned_formatter.rs.jinja

+11-3
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,11 @@ pub mod ffi {
190190
let mut input = icu_datetime::DateTimeInputUnchecked::default();
191191
{%- if flavor.has_date() %}
192192
{%- if formatter_kind.is_fixed_calendar %}
193-
let date = date.0.to_calendar(Gregorian);
193+
let date_in_calendar = date.0.to_calendar(Gregorian);
194194
{%- else %}
195-
let date = date.0.to_calendar(self.0.calendar());
195+
let date_in_calendar = date.0.to_calendar(self.0.calendar());
196196
{%- endif %}
197-
input.set_date_fields_unchecked(date); // calendar conversion on previous line
197+
input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
198198
{%- endif %}
199199
{%- if flavor.has_time() %}
200200
input.set_time_fields(time.0);
@@ -206,6 +206,14 @@ pub mod ffi {
206206
if let Some(zone_name_timestamp) = zone.zone_name_timestamp {
207207
input.set_time_zone_name_timestamp(zone_name_timestamp);
208208
}
209+
{%- if flavor.has_date() && flavor.has_time() %}
210+
else {
211+
input.set_time_zone_name_timestamp(icu_time::zone::ZoneNameTimestamp::from_date_time_iso(&icu_time::DateTime {
212+
date: date.0,
213+
time: time.0
214+
}))
215+
}
216+
{%- endif %}
209217
if let Some(variant) = zone.variant {
210218
input.set_time_zone_variant(variant);
211219
}

0 commit comments

Comments
 (0)