Help with chrono and chrono-tz

When using chrono::offset::Utc or chrono::offset::FixedOffset (although I don't know the difference between them), I can use DateTime::from_str just fine. But when using chrono_tz::Tz, I've no idea how I can do that.

impl TryFrom<&str> for ZonedDateTime {
    type Error = RangeError;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        Ok(ZonedDateTime {
            inner: <chrono::DateTime::<chrono_tz::Tz> as std::str::FromStr>::from_str(value).or(Err(RangeError))?,
            calendar: Calendar::Iso8601,
        })
    }
}

Also this isn't compiling anymore with chrono_tz::Tz. It requires TzOffset, and I'm receiving Tz:

pub fn to_zoned_date_time(&self, timezone: TimeZone, calendar: Calendar) -> Result<ZonedDateTime, RangeError> {
    match calendar {
        Calendar::Iso8601 => Ok(ZonedDateTime {
            calendar,
            inner: chrono::DateTime::<chrono_tz::Tz>::from_utc(chrono::naive::NaiveDateTime::from_timestamp_millis(self.epoch().milliseconds()).ok_or(RangeError)?, timezone.0),
        }),
    }
}

Besides the top problem, I also want to be able to convert back to string. This string isn't for internationalization; it's just the standard exchange date-time string.

What's your goal with using chrono_tz::Tz over chrono::offset::FixedOffset?

The difference between Utc and FixedOffset is that FixedOffset stores the offset of the timezone in each instance of the type. Utc is a special case of FixedOffset where the offset is constant, so it's just a unit struct. If you can always work in Utc then you can avoid having to store that offset all over.

chrono::DateTime only implements FromStr for the time zone types in chrono::offset. You may need to use the chrono::format module to parse the date semi-manually

You haven't provided enough information for me to be able to figure out what "won't compile" means.

2 Likes

To avoid an XY problem, and based on the fact that you have stated that you don't know the differences between two date formats, I would first ask you: what are you trying to achieve? Dealing with dates can get complex and, since you are using zoned date times, I think you might be trying to convert dates coming from the browser on the server-side, which is a no-no.

1 Like

It looks like Tz allows you to construct a timezone from a "timezone string" (i.e. Europe something) by collecting data from the IANA database.

In that case I just wanted to let you be able to express dates as string literals instead of C { year: n, month: n, ..etc }.

timezone parameter in to_zoned_date_time() is this:

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct TimeZone(pub(crate) chrono_tz::Tz);

chrono::DateTime::from_utc() expected timezone.0 to be a chrono_tz::TzOffset and I specified a chrono_tz::Tz instead.

First, I don't want to build a "website building" platform.

I'm trying to mimmick Flutter and Adobe AIR, but in the Rust language, and am foundating an API that wraps other crates, aliases some (for example, the regex crate and lazy_regex crates are aliased as reg_exp! etc.) and provides additional things that are often used into a called "utilities API".

I want a temporal API inside this utilities API that mimmicks the TC39 proposal, but isn't a 1-1 mapping... I don't want it to be generic over a timezone so that it's not just the same as chrono and works kind of independent (but still relies on it internally).

I would then don't care about timezones, and simply deal with dates in ISO 8601 format.

To do that, you could take a look at Chrono's DateTime.

You would use it like this:

  1. On the JavaScript side, convert the dates to ISO strings with the toISOString method
  2. On Rust's side, you would use DateTime<Utc> as your date type when deserializing the dates coming from JavaScript.
1 Like

I discovered recently that chrono already detects the browser as the wasm32 target and, if the wasmbind feature is enabled (enabled by default), it uses the browser's Date. I'm also targetting cross-platform, so it must work everywhere.

If I discard chrono_tz to use always DateTime<Utc>, that means I'll only support the browser unless I work myself on my own alternative...

Yes. When dealing with dates I think that, as a rule-of-thumb, you should have only one source-of-truth. Otherwise, you are opening yourself to inconsistencies in your system, since users can simply change the dates on their devices to whatever they want.

That's chrono's default behavior, so there's nothing wrong on not worrying about whether it's using the browser or not?

Aw, should I write my alternative to chrono then?

I'll waste a lot of time if I do this...

If you want to maintain interoperability with the rest of the ecosystem, I suggest you to keep using Chrono.

1 Like