Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Platform Support #140

Closed
daylightwarbler opened this issue Oct 8, 2024 · 9 comments · Fixed by #199
Closed

Android Platform Support #140

daylightwarbler opened this issue Oct 8, 2024 · 9 comments · Fixed by #199
Labels
platform Issues related to platform support.

Comments

@daylightwarbler
Copy link

daylightwarbler commented Oct 8, 2024

Getting the current time works as expected, but using the system Time Zone Database and obtaining the system time zone both require additional crates and lower-level Jiff methods. If Android was supported out of the box, then that would also improve ergonomics for cross-platform Android/iOS projects, since Jiff's API could be used the same way on both targets.

On Android, the Time Zone Database is in an Android-specific format. The android-tzdata crate provides TZif data for a time zone name.

use jiff::{civil::date, tz::TimeZone};

let tz_name = "America/New_York";
let tz_data = android_tzdata::find_tz_data(tz_name)?;
let tz = TimeZone::tzif(tz_name, &tz_data)?;
let zdt = date(2023, 12, 31).at(18, 30, 0, 0).to_zoned(tz)?;
assert_eq!(zdt.to_string(), "2023-12-31T18:30:00-05:00[America/New_York]");

The system time zone can be obtained with the iana-time-zone crate.

use jiff::{tz::TimeZone, Timestamp};

let tz_name = iana_time_zone::get_timezone()?;
let tz_data = android_tzdata::find_tz_data(&tz_name)?;
let tz = TimeZone::tzif(&tz_name, &tz_data)?;
let zdt_now = Timestamp::now().to_zoned(tz);
@BurntSushi BurntSushi added the platform Issues related to platform support. label Oct 8, 2024
@BurntSushi
Copy link
Owner

Yeah I do want to support this automatically. But I wanted a concrete thing I could test somehow first. Is there an example Rust program along with perhaps a CI setup that demonstrates the full end to end need here?

Basically, I haven't written Rust programs on Android before. I do have a good idea of what needs to be done based on prior art research, but I don't know exactly how I should go about iterating and testing. If someone can help me with that part, then I can do the rest.

@daylightwarbler
Copy link
Author

daylightwarbler commented Oct 10, 2024

Ok, here’s an example Android app build with Jiff and a Github actions CI workflow.

https://github.com/daylightwarbler/android-rust-example

@BurntSushi
Copy link
Owner

Thank you! I managed to get that to work after a lot of faffing about. Holy shit what a complex nightmare. But I think that's enough for me to iterate. Thanks again.

@BurntSushi
Copy link
Owner

Oh, is there an easy way to make BAZEL build a copy of Jiff from my local disk instead of taking it from the crate index? Specifically, this part:

https://github.com/daylightwarbler/android-rust-example/blob/5327693d1afba0213b5ce9b7ef029120feb6c579/rust/BUILD#L4-L15

BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
BurntSushi added a commit that referenced this issue Jan 12, 2025
Android support has two prongs:

* The special Android concatenated time zone database will now be read
  by Jiff automatically.
* The `persist.sys.timezone` Android property is read to determine the
  system's configured IANA time zone identifier.

Closes #140
@BurntSushi
Copy link
Owner

OK, I managed to get this working. It should be available automatically in jiff 0.1.22 on crates.io. Please see the platform docs for Android for more specific details.

@dead10ck
Copy link

Looks like this does not compile on-device from a Termux shell. There are 5 instances of this error:

error[E0308]: mismatched types
   --> /data/data/com.termux/files/home/.cargo/registry/src/index.crates.io
-6f17d22bba15001f/jiff-0.1.22/src/tz/system/android.rs:117:38
    |
117 | ...= unsafe { dlopen(cstr("libc.so\0").as_ptr(), 0) };
    |               ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*const i8`,
 found `*const u8`
    |               |
    |               arguments to this function are incorrect
    |
    = note: expected raw pointer `*const i8`
               found raw pointer `*const u8`
note: function defined here
   --> /data/data/com.termux/files/home/.cargo/registry/src/index.crates.io
-6f17d22bba15001f/jiff-0.1.22/src/tz/system/android.rs:293:8
    |
293 |     fn dlopen(filename: *const i8, flag: i32) -> *mut c_void;
    |        ^^^^^^

@BurntSushi
Copy link
Owner

Wat. Can you open a new issue and give steps for a reproduction please?

@BurntSushi
Copy link
Owner

Also, can you include the target triple?

BurntSushi added a commit that referenced this issue Jan 12, 2025
I guess some platforms use `*const u8` for C strings while most
seemingly use `*const i8`. So insert a bunch of `.cast()` calls where
appropriate.

Ref #140

Fixes #200
@BurntSushi
Copy link
Owner

I created a new issue for that in #200. But would still love a repro that I can follow along with (speaking as someone who has never used termux before) and a target triple so that I can see about adding it to CI.

BurntSushi added a commit that referenced this issue Jan 13, 2025
I guess some platforms use `*const u8` for C strings while most
seemingly use `*const i8`. And indeed, `CStr::as_ptr` returns a
`*const u8` or a `*const i8` depending on the platform. So do the right
thing here and use std's `c_char` alias.

Ref #140

Fixes #200
BurntSushi added a commit that referenced this issue Jan 13, 2025
I guess some platforms use `*const u8` for C strings while most
seemingly use `*const i8`. And indeed, `CStr::as_ptr` returns a
`*const u8` or a `*const i8` depending on the platform. So do the right
thing here and use std's `c_char` alias.

Ref #140

Fixes #200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform Issues related to platform support.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants