in src/serialize/per_type/datetimelike.rs [44:146]
fn year(&self) -> i32;
/// Returns the month component of the datetime.
fn month(&self) -> u8;
/// Returns the day component of the datetime.
fn day(&self) -> u8;
/// Returns the hour component of the datetime.
fn hour(&self) -> u8;
/// Returns the minute component of the datetime.
fn minute(&self) -> u8;
/// Returns the second component of the datetime.
fn second(&self) -> u8;
/// Returns the number of microseconds since the whole non-leap second.
fn microsecond(&self) -> u32;
/// Returns the number of nanoseconds since the whole non-leap second.
fn nanosecond(&self) -> u32;
/// Is the object time-zone aware?
fn has_tz(&self) -> bool;
//// python3.8 or below implementation of offset()
fn slow_offset(&self) -> Result<Offset, DateTimeError>;
/// The offset of the timezone.
fn offset(&self) -> Result<Offset, DateTimeError>;
/// Write `self` to a buffer in RFC3339 format, using `opts` to
/// customise if desired.
#[inline(never)]
fn write_buf(&self, buf: &mut SmallFixedBuffer, opts: Opt) -> Result<(), DateTimeError> {
{
let year = self.year();
let mut yearbuf = itoa::Buffer::new();
let formatted = yearbuf.format(year);
if unlikely!(year < 1000) {
// date-fullyear = 4DIGIT
buf.extend_from_slice(&[b'0', b'0', b'0', b'0'][..(4 - formatted.len())]);
}
buf.extend_from_slice(formatted.as_bytes());
}
buf.push(b'-');
write_double_digit!(buf, self.month());
buf.push(b'-');
write_double_digit!(buf, self.day());
buf.push(b'T');
write_double_digit!(buf, self.hour());
buf.push(b':');
write_double_digit!(buf, self.minute());
buf.push(b':');
write_double_digit!(buf, self.second());
if opt_disabled!(opts, OMIT_MICROSECONDS) {
let microsecond = self.microsecond();
if microsecond != 0 {
buf.push(b'.');
write_triple_digit!(buf, microsecond / 1_000);
write_triple_digit!(buf, microsecond % 1_000);
// Don't support writing nanoseconds for now.
// If requested, something like the following should work,
// and `SmallFixedBuffer` needs at least length 35.
// let nanosecond = self.nanosecond();
// if nanosecond % 1_000 != 0 {
// write_triple_digit!(buf, nanosecond % 1_000);
// }
}
}
if self.has_tz() || opt_enabled!(opts, NAIVE_UTC) {
let offset = self.offset()?;
let mut offset_second = offset.second;
if offset_second == 0 {
if opt_enabled!(opts, UTC_Z) {
buf.push(b'Z');
} else {
buf.extend_from_slice(b"+00:00");
}
} else {
// This branch is only really hit by the Python datetime implementation,
// since numpy datetimes are all converted to UTC.
if offset.day == -1 {
// datetime.timedelta(days=-1, seconds=68400) -> -05:00
buf.push(b'-');
offset_second = 86400 - offset_second;
} else {
// datetime.timedelta(seconds=37800) -> +10:30
buf.push(b'+');
}
let offset_minute = offset_second / 60;
let offset_hour = offset_minute / 60;
write_double_digit!(buf, offset_hour);
buf.push(b':');
let mut offset_minute_print = offset_minute % 60;
// https://tools.ietf.org/html/rfc3339#section-5.8
// "exactly 19 minutes and 32.13 seconds ahead of UTC"
// "closest representable UTC offset"
// "+20:00"
let offset_excess_second =
offset_second - (offset_minute_print * 60 + offset_hour * 3600);
if offset_excess_second >= 30 {
offset_minute_print += 1;
}
write_double_digit!(buf, offset_minute_print);
}
}
Ok(())
}