How to save time in the database in Go when using GORM and Postgresql? - 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

Related

TIMESTAMP- creation_date :: date between '2022-05-15' and '2022-06-15'

I just wanted to know the difference between these two codes:
select count (user_id) from tb_users where
creation_date :: date between '2022-05-15' and '2022-06-15'
Result: 41,232
select count (user_id) from tb_users where
creation_date between '2022-05-15' and '2022-06-15'
Result: 40,130
As far as I see, it is related with the timestamp, but I do not understand the difference.
Thank you!
Your column creation_date in the table is most probably in timestamp format, which is '2022-05-15 00:00:00'. By adding ::date <- you are casting your timestamp format to date format: '2022-05-15'.
You can read more about casting data types here:
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-cast/
When you ask Postgres to implicitly coerce a DATE value to a TIMESTAMP value - the hours, minutes and seconds are set to zero.
In the first query, you explicitly cast the creation date to DATE which is successfully compared to the provided DATE values.
In the second query, the creation date is of type TIMESTAMP and so PostgreSQL converts your DATE values to TIMESTAMP values and the comparison becomes
creation_date >= '2022-05-15 00:00:00' AND creation_date <= '2022-06-15 00:00:00'
Obviously, this produces different resultset than the first query.

GORM PostgreSQL getting date column without timezone

I'm learning golang atm, and currently I'm using gorm trying to select query getting date column, but it keep returning '2020-01-10T00:00:00Z', how do I get rid of the timezone?
I've tried changing date to time.Time or string, nothing works, here is the code
type Price struct {
DateStay time.Time `json:"date"`
Price int `json:"price"`
}
Update:
This is the code that I am using
var price []models.Price
err = models.DB.Raw(`
SELECT P.date_stay, P.price
FROM prices p
WHERE P.room_type_id = ?
`, roomTypeId).Scan(&price).Error
I tried to P.date_stay::date, date(P.date_stay) on the query but nothing works
I expect it to return '2020-01-10'
Using time.Time as a type for the date is probably best.
You can format the result of the date by setting the format to the desired date format you want.
(dd-mm-yyyy or whatever order you please).
Then you can format the value using time.Parse(format, date)
format := "2000-01-13"
formattedDate, err := time.Parse(format, price.DateStay)
assuming price is a result from your select query.
If you time is a time.Time you can try using price.DateStay.Format(format)

Inserting CURRENTDATE for DATE column fails in PostgreSQL

i am trying to insert CURRENTDATE as the value for a field that has the type defined as "Timestamp without Timezone".
INSERT INTO monthly_forecasts VALUES
('1','DIV1','Mon','Tue','Wed','Thu','Fri','','','','','-3',CURRENTDATE, CURRENTDATE)
But I get this error when I do that:
ERROR: column "currentdate" does not exist
LINE 2: ...'Mon','Tue','Wed','Thu','Fri','','','','','-3',CURRENTDAT...
^
How do I insert current date as the value for this field? Please help!
As documented in the manual the function is named current_date, not currentdate.
But as your column is defined as timestamp, you should use current_timestamp to include the time of the day (a DATE doesn't have a time)

How to do a TIMESTAMP comparison in mongo DB?

I have the following field in all my documents. And the Timestamp below will always be in string and I have no control to change it into any other type.
{ "TIMESTAMP": "2017-09-07T16:43:08.707-04:00" }
Since it is -04:00 the timestamp is in EST. but it can be in any timezone like -05:00 or -6:00 or whatever
The goal is to get all the documents that match the following criteria
currentTime > TIMSETAMP + 4 hours
where currentTime is in UTC and it is something I generate when I query.
I tried something like the following and I am not sure if there is anything wrong with this approach.
(new Date()- ISODate("2017-09-07T16:43:08.707-04:00"))/(60*60*1000) > 4

problems to get the full DATE info from Oracle DB (dd/mm/yyyy hh/mm/ss)

I have a column in a table in which we are storing date in DATETIME format. (DD-MON-RRRR HH24:MI:SS) - Database Oracle 11g.
Data Type of a column is DATE, and storing date in 01-01-2012 01:00 PM (i.e. jan 1, 2012) format.
entity
#NotNull
#Column(name = "dateColumnName")
#Temporal(TemporalType.TIMESTAMP)
private Date sampleDate;
I am fetching all data by passing date
SAMPLE_QUERY = "select * from TableA tab where tab.dateWithTime = :sampleDate order by tab.dateWithTime ASC "
singleDate is "Tue Jan 24 00:00:00 IST 2012" , fasttime :
1327343400000
The problem is I am passing only date in the query, though Date through which records are being fetched is in DATE TIME format i.e 01-01-2012 01:00 PM.
How can i change my query so that it fetches all the records in ascending order of DateTime.
If you want to fetch all times for that day, then change your query to be more like
SELECT ... WHERE dateField >= :lowerParam AND dateField < :upperParam
Oracle has no DATE TIME datatype. The DATE datatype contains both a date and a time component, down to the second. TIMESTAMPS get a bit more complicated.
If your dateWithTime column is indeed a DATE datatype, the ORDER BY dateWithTime ASC clause should order your results in ascending order.
You may not be displaying the time component of your date. You can convert a date to a string in that format with TO_CHAR( dateWithTime, 'dd/mm/yyyy hh24/mm/ss' ) or whatever format you want.
Edit:
Oh, do you mean you want to find the cases where the date component of the DATE matches, but you don't care about the time component? That can be handled in the where clause with something like:
WHERE TRUNC( tab.dateWithTime ) = TRUNC( :sampledate )
TRUNC by default truncates a date to the beginning of the day.