Convert Postgres timestamp to Rust Chrono - postgresql

How to covert a PostgreSQL timestamp (with time zone) to Rust Chrono DateTime<Utc>?
Example: 2020-04-12 22:10:57.0+02

You have to use the custom parser from str:
let date_str = "2020-04-12 22:10:57.000+02";
// convert the string into DateTime<FixedOffset>
let datetime = DateTime::parse_from_str(&date_str, "%Y-%m-%d %H:%M:%S%.f%#z").unwrap();
// convert the string into DateTime<Utc> or other timezone
let datetime_utc = datetime.with_timezone(&Utc);
Extra info:
%.f => .026490: Similar to .%f but left-aligned. These all consume the leading dot.
%#z => +09: Parsing only: Same as %z but allows minutes to be missing or present.
For more info, see this awnser.

The Postgres type TIMESTAMP is only convertible to chrono's NaiveDateTime.
In order to convert to chrono's DateTime<Utc>, you must use the Postgres type TIMESTAMP WITH TIME ZONE for your column.

Related

How to query a Timestamptz with a Unix timestamp using Diesel?

I can easily get the system Unix millisecond timestamp, but how can I convert it into something I can query with Diesel? The table in my schema has a Timestampz field (timestamp with time zone) that I need to compare to the Unix timestamp.
use diesel::sql_types::Timestamptz;
fn main() {
let unix_time: i64 = 123456;
let time: Timestamptz = ???
}
[dependencies]
diesel = { version = "1.4.7", features = ["postgres"] }
Timestamptz can be created from a PgTimestamp, chrono::NaiveDateTime or chrono::DateTime according to the docs.
I don't think there is a direct way to generate a timestamptz, and it's supposed to be opaque in most instances. Instead where a queries requires a Timetamptz you can pass a NaiveDateTime and load a NaiveDateTime back.
Now we use NaiveDateTime as it's the only one that can be created from a unix timestamp. DateTime requires an explicit timezone and can be generated from a NaiveDateTime.
use chrono::NaiveDateTime;
fn main() {
let conn = get_connection();
let ndt = NaiveDateTime::from_timestamp(0, 42_000_000);
let (id, date) = users
// assume a "created" column being a Timestamptz
// you can just pass a NaiveDateTime.
.filter(created.gt(ndt))
.select((user_id, created))
// We load back a NaiveDateTime and never deal with Timestamptz directly.
.first::<(u64, NaiveDateTime)>(&conn)
.expect("query failed");
}

Convert using unixtimestamp to Date

I have a field in a dataframe that has a column with date like 1632838270314 as an example
I want to convert it to date like 'yyyy-MM-dd' I have this so far but it doesn't work:
date = df['createdOn'].cast(StringType())
df = df.withColumn('date_key',unix_timestamp(date),'yyyy-MM-dd').cast("date"))
createdOn is the field that derives the date_key
The method unix_timestamp() is for converting a timestamp or date string into the number seconds since 01-01-1970 ("epoch"). I understand that you want to do the opposite.
Your example value "1632838270314" seems to be milliseconds since epoch.
Here you can simply cast it after converting from milliseconds to seconds:
from pyspark.sql import functions as F
df = sql_context.createDataFrame([
Row(unix_in_ms=1632838270314),
])
(
df
.withColumn('timestamp_type', (F.col('unix_in_ms')/1e3).cast('timestamp'))
.withColumn('date_type', F.to_date('timestamp_type'))
.withColumn('string_type', F.col('date_type').cast('string'))
.withColumn('date_to_unix_in_s', F.unix_timestamp('string_type', 'yyyy-MM-dd'))
.show(truncate=False)
)
# Output
+-------------+-----------------------+----------+-----------+-----------------+
|unix_in_ms |timestamp_type |date_type |string_type|date_to_unix_in_s|
+-------------+-----------------------+----------+-----------+-----------------+
|1632838270314|2021-09-28 16:11:10.314|2021-09-28|2021-09-28 |1632780000 |
+-------------+-----------------------+----------+-----------+-----------------+
You can combine the conversion into a single command:
df.withColumn('date_key', F.to_date((F.col('unix_in_ms')/1e3).cast('timestamp')).cast('string'))

How to convert unix timestamp to iso 8601 in Flutter

I am getting date from a server as a unix timestamp, how can I convert it to ISO 8601 date format in flutter?
the date I receive:
1611694800000
How I want to convert it to be
2021-01-26T22:00:00.000+00:00
What I have done so far with no luck
String s = '1611694800000';
debugPrint("Recevied date is: $s");
String dateS = DateTime.parse(s).toIso8601String();
debugPrint("Converted date : $dateS");
String dateStr = (dateS.split(".")[0].split("T")[0] + " 00:00:00").substring(1);
debugPrint("Activation date: $dateStr");
I end up getting:
Unhandled Exception: FormatException: Invalid date format.
Use DateTime.fromMillisecondsSinceEpoch:
var timestampMilliseconds = 1611694800000;
var datetime =
DateTime.fromMillisecondsSinceEpoch(timestampMilliseconds, isUtc: true);
print(datetime.toIso8601String()); // Prints: 2021-01-26T21:00:00.000Z
(Note that the printed time is one hour off of your stated expectation, but I'm assuming that's a mistake in your expectation.)
The reason why you are getting invalid date format is because you have to provide date in string like '2021-04-19' and not milliseconds;
This package makes it easy to format dates time_formatter

R: Converting timestamp to date

I have a timestamp pulled from MongoDB
example: 2007-01-01 01:00:00
I need it to be a simple date: 2007-01-01
Been looking at: Convert UNIX epoch to Date object
Having a hard time formatting
Using sources:
Convert column in data.frame to date
I had to assess if the class that I was trying to convert was a class that as.Date was able to take.
Turns out it was a data.frame class
Used the following to convert it:
dat_dump %>%
mutate( date = as.Date(date, format = "%Y-%m-%d"))

How to save time in the database in Go when using GORM and Postgresql?

I'm currently parsing a time string and saving it to the db (Postgresql):
event.Time, _ := time.Parse("3:04 PM", "9:00 PM")
// value of event.Time now is: 0000-01-01 21:00:00 +0000 UTC
db.Create(&event)
It's giving me this error: pq: R:"DateTimeParseError" S:"ERROR" C:"22008" M:"date/time field value out of range: \"0000-01-01T21:00:00Z\"" F:"datetime.c" L:"3540"
event.Time⁠⁠⁠⁠'s type is time.Time.
I also tried setting event.Time's type to string and using time data type in postgresql:
type Event struct {
Time string `gorm:"type:time
}
But now I'm getting an error when fetching records in the db:
sql: Scan error on column index 4: unsupported driver -> Scan pair: time.Time -> *string
Investigated this issue further. Currently, there's no support in GORM for any Date/Time types except timestamp with time zone
See this part of code from dialect_postgres.go:
case reflect.Struct:
if _, ok := dataValue.Interface().(time.Time); ok {
sqlType = "timestamp with time zone"
}
So basically I see two options for you:
Either use varchar(10) in DB, and string in Go, an simply save it as "9:00 PM" (where 10 is some number that suits you)
Or use timestamp with time zone in DB, time.Time in Go, and format your date part as a constant date, 01/01/1970, for example:
time.Parse("2006-01-02 3:04PM", "1970-01-01 9:00PM")
In that case you'll have to omit the date part in your presentation, but if you plan to select by date range, that could work better for you.
You can set an arbitrary database-specific type with Gorm using sql tag
type Event struct {
Time time.Time `sql:"type:timestamp without time zone"`
}
When updating the DATETIME field in SQL, the Go string must be in this format: time.Now().Format(time.RFC3339).
From Postgres perspective the error stems from there being no year 0000. If you don't the date you may just be able to add 1 year to the converted timestamp giving '0001-01-01T21:00:00+00' which is a valid Postgres timestamp.
select '0000-01-01T21:00:00+00'::timestamptz at time zone 'UTC'
ERROR: date/time field value out of range: "0000-01-01T21:00:00+00"
Gives he same error. And just as a demonstration 1 day before 0001-01-01 gives:
select '0001-01-01T21:00:00+00'::timestamptz at time zone 'UTC' - interval '1 day' "day_before_1/1/1";
--day_before_1/1/1
--0001-12-31 21:00:00 BC