GORM PostgreSQL getting date column without timezone - postgresql

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)

Related

Postgres OVERLAPS date function in TypeORM

I want to transfer the query to TypeORM.
It looks like this in Postgres
SELECT *
from equipment_charging
where (equipment_charging."start_date"::date, equipment_charging."end_date"::date) OVERLAPS (DATE '2020-09-10', DATE '2020-09-14')
I'm writing this query in TypeORM like this:
.where(
'(equipment_charging.startDate::date, equipment_charging.endDate::date) OVERLAPS (DATE :startDate, DATE :endDate)',
{ startDate, endDate },
)
it gives me error like this:
{"context":"ExceptionsHandler","stack":["QueryFailedError: syntax error at or near \"$1\"\n at new QueryFailedError
What am I doing wrong?
If equipment_charging.startDate and equipment_charging.endDate are already date type in database I think that you could remove ::date
In same idea try to give directly date type for the input.
I also use lot of double quote for query builder in typeorm
try this:
.where(
'("equipment_charging"."startDate", "equipment_charging"."endDate") OVERLAPS (:startDate, :endDate)',
{ startDate, endDate },
)
And convert startDate and endDate to date if needed (with parseIso of date fns for example)

Create an inserted_at datetime where filter using simple date string

I'm trying to get records inserted after a certain date given to me by the client.
2018-06-06
Here's how I'm writing the query:
{:ok, date} = NaiveDateTime.from_iso8601(date_string)
from(
m in query,
where: m.inserted_at > ^date
)
(MatchError) no match of right hand side value: {:error, :invalid_format}
And when I try to use a simple Date object:
** (Ecto.Query.CastError) lib/messages/search.ex:77: value ~D[2018-06-06] in where cannot be cast to type :naive_datetime in query
How can I find all messages inserted after that dummy string date the client is passing me?
You have an ISO 8601 date there, not a datetime. You can convert it into a NaiveDateTime (with hour, minute, second all set to 0) like this:
iex(1)> date_string = "2018-06-06"
"2018-06-06"
iex(2)> ndt = NaiveDateTime.from_iso8601!(date_string <> " 00:00:00")
~N[2018-06-06 00:00:00]
Now you can use ndt in your query and it will work.

Converting date format in denodo database

I'm trying to convert value for DIM_DT_ID to MMddYY. I'm successful in doinf that. However, query fails because ultimately I'm comparing a character value to date here. Is there a way by which I can get value for DIM_DT_ID in MMddyy format and its data type still remains DATE ?
Here DIM_DT_ID
SELECT DIM_DT_ID
DIM_DT_ID >= FORMATDATE('MMddyy',ADDDAY(TO_date('yyyy-MM-dd','2016-12-21'), -25)); from abc;
Regards,
Ajay
In Denodo, to convert a string to a date field, use "to_date()" (which returns a date).
Then, don't convert back to a string, leave that field as a date (so don't use "Formatdate()", which returns a string).
So:
SELECT *
FROM MyTable
WHERE now() >= to_date('yyyy-MM-dd',myStringFieldThatLooksLikeADate)
In my example, "now()" is a date, and so is the output of the to_date function... so you can do a comparison.
If you try to convert the date back to a string using formatdate, it won't work:
#This doesn't work:
SELECT *
FROM MyTable
WHERE now() >= formatdate('MMddyy',to_date('yyyy-MM-dd',myStringFieldThatLooksLikeADate))
It doesn't work because we are comparing a date ("now()") to a string.

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

What type should you store the date in a database?

Currently I'm storing it as a String, but got problems using it when it comes to querying by date with GQL.
Date date = Calendar.getInstance().getTime();
DateFormat formatter = new SimpleDateFormat("hh:mm:ss, z");
String todayDate = formatter.format(date);
The query:
"SELECT FROM SomeTable p WHERE date = 01/01/2011"
Error:
Exception:
org.datanucleus.store.appengine.query.DatastoreQuery$UnsupportedDatastoreFeatureException:
Problem with query : Right side of expression is
composed of unsupported components.
Left:
org.datanucleus.query.expression.Literal,
Op: / , Right:
DyadicExpression{Literal{5} /
Literal{11}}
How can I search by date?
Always as a date - the database should check on the types of data that it stores thus making sure the data is what it says. the information about what type is known on the insert so check it then rather than later when none has any idea of what the correct value should have been.
the error you are getting is probably not due to this but because the date in the query needs to be made a date if types are correct or if a string needs to be as a single-quoted string see GQL Reference
e.g.
"SELECT FROM SomeTable p WHERE date = '01/01/2011'"
but what date is 06/07/2011 ? I think it is today 6th July, others 7th June. So even if you use strings use the ISO format 2011-07-06 A date type will hide this detail making it easier. Note that GQL only uses the ISO form so even if you got the command to have the date in a string it would fail.
but better as
SELECT FROM SomeTable p WHERE date = DATE( 2011, 1, 1)