I have this table in postgresql
CREATE TABLE remise
(
id bigserial NOT NULL,
date_remise time without time zone
)
and this code to insert a row into it via eclipselink :
Remise rm = new Remise();
rm.setId(1L);
rm.setDateRemise(Calendar.getInstance().getTime()); //today
dao.begin();
dao.save(rm);
dao.commit();
in the Remise Entity class I have this field with it's getter and setter :
#Column(name = "date_remise")
#Temporal(TemporalType.TIME)
private Date dateRemise;
everything looks ok but the date I get inserted is like that with just time and no date !
in pgAdmin III : "03:16:03"
via my application : "Thu Jan 01 03:16:03 WET 1970"
I'm using : Postgresql 9.3, 9.1-901-1.jdbc4, eclipselink 2.5.2.
Need your help to fix this problem. thanks.
You need to use timestamp without time zone.
time without time zone only stores time portion.
thank you araqnoon for the correct response, just one precision for the mapping of the field it must look like :
#Column(name = "date_remise")
#Temporal(TemporalType.TIMESTAMP)
private Date dateRemise;
Related
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
I'm trying to import data from a superoffice caesar crm SQL database.
In this database there is a column called CreateDATE which is a float.
What is the proper way to convert this to yyyy-MM-dd hh:mm:ss format?
The column
I tried something like this but it's not matching the date seen in the program so I'm guessing there something more to this?
Figured it out.
Select
dateadd(d,UpdateDATE,'1899-12-30')
from Activity where CustomerID = xxx order by UpdateDATE desc
Use CAST or CONVERT as the below:
DECLARE #DateVal DATETIME = '2016-08-12 13:57:15.347'
SELECT CAST(#DateVal AS FLOAT) -- 42592,5814276235
DECLARE #FloatVal FLOAT = 42592.5814276235
SELECT CAST(#FloatVal AS DATETIME) -- 2016-08-12 13:57:15.347
Since I am already getting down voted I decided to give some more details to my problem.
My problem is that I want to store times. Times only for easy comparison. To me it makes sense to define it as following:
00:00:00 = (long) 0L
24:00:00 = (long) 24*60*60*1000L
The PostgreSQL documentation says about TIME WITHOUT TIME ZONE this:
time [ (p) ] [ without time zone ]
8 bytes | time of day (no date) | 00:00:00 - 24:00:00 | 1 microsecond / 14 digits
But for some reason, somewhere along the way from my database to my web application the timestamps are getting messed up.
In the following I want to show you that I am storing TIME WITHOUT TIME ZONE, mapped from LocalTime (jodatime), into my database and afterwards fetch it back.
Fetching it back from the database and mapping it back into a LocalTime object will give me something like 23 Feb 2016 08:00:00 GMT which is
1456214400000 and that is > 24*60*60*1000.
There are 3 to 4 options:
PostgresSQL stores actually the whole TIMESTAMP and shows HH:mm:ss just for presentation
jodatime is inventing things here that are not there.
(very unlikely) The mapper I am using does more than I tell him. But that is unlikely since the mapper does not touch anything.
(probably true) I myself mess things up somehow.
More details:
I decided to add some more details. I am creating a record for my table shop_times
private Long createShopTimes(Long shopId, DateTime dayFrom, DateTime dayTo, LocalTime timeFrom, LocalTime timeTo, DayOfWeek dayOfWeek, ShopTimesType shopTimesType) {
Long timePeriodId = this.ctx.insertInto(SHOP_TIMES)
.set(SHOP_TIMES.SHOP_ID, shopId)
.set(SHOP_TIMES.DAY_OF_WEEK_ID, dayOfWeek)
.set(SHOP_TIMES.SHOP_TIMES_TYPE_ID, shopTimesType)
.set(SHOP_TIMES.DAY_FROM, dayFrom)
.set(SHOP_TIMES.DAY_TO, dayTo)
.set(SHOP_TIMES.TIME_FROM, timeFrom)
.set(SHOP_TIMES.TIME_TO, timeTo)
.returning(SHOP_TIMES.ID)
.fetchOne().getValue(SHOP_TIMES.ID);
List<ShopTimesRecord> fetchInto = this.ctx.select(
SHOP_TIMES.TIME_FROM,
SHOP_TIMES.TIME_TO
)
.from(SHOP_TIMES)
.fetchInto(ShopTimesRecord.class);
for (ShopTimesRecord shopTimesRecord : fetchInto) {
if(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis() > 24*60*60*1000L) {
System.err.println("This should not happen..");
}
Date from = new Date(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis());
Date to = new Date(shopTimesRecord.getTimeTo().toDateTimeToday().getMillis());
System.out.println(from.toGMTString());
System.out.println(shopTimesRecord.getTimeFrom().toDateTimeToday().getMillis());
System.out.println(to.toGMTString());
System.out.println(shopTimesRecord.getTimeTo().toDateTimeToday().getMillis());
}
return timePeriodId;
}
As you can see, I am getting something that I would not expect at this point:
This should not happen..
23 Feb 2016 08:00:00 GMT
1456214400000
23 Feb 2016 20:00:00 GMT
1456257600000
This is the table shop_times that I am using to store timing information:
CREATE TABLE shop_times (
-- PRIMARY KEY
id BIGSERIAL PRIMARY KEY,
-- FOREIGN KEYS
shop_id BIGINT NOT NULL,
CONSTRAINT fk__shop_times__shop
FOREIGN KEY (shop_id)
REFERENCES shop(id),
shop_times_type_id BIGINT NOT NULL,
CONSTRAINT fk_shop_times__shop_times_type
FOREIGN KEY (shop_times_type_id)
REFERENCES shop_times_type(id),
day_of_week_id BIGINT NOT NULL,
CONSTRAINT fk__shop_times__day_of_week
FOREIGN KEY (day_of_week_id)
REFERENCES day_of_week(id),
-- ATTRIBUTES
day_from TIMESTAMP WITH TIME ZONE NOT NULL,
day_to TIMESTAMP WITH TIME ZONE NOT NULL,
time_from TIME WITHOUT TIME ZONE NOT NULL,
time_to TIME WITHOUT TIME ZONE NOT NULL,
-- CONSTRAINTS
CHECK(day_from < day_to),
CHECK(time_from < time_to)
);
The mapper I am using. But as you can see it is just taking the time it gets and passes it further;
public class TimeWithoutTzToJodaLocalTimeConverter implements Converter<Time, LocalTime> {
private static final long serialVersionUID = -2736422625956918206L;
#Override
public LocalTime from(Time timestamp) {
LocalTime dateTime = new LocalTime(timestamp.getTime());
return dateTime;
}
#Override
public Time to(LocalTime localTime) {
Time time = new Time(localTime.toDateTimeToday().getMillis());
return time;
}
#Override
public Class<Time> fromType() {
return Time.class;
}
#Override
public Class<LocalTime> toType() {
return LocalTime.class;
}
}
Sorry - don't believe you.
=> SELECT '24:00:00'::time without time zone;
time
----------
24:00:00
(1 row)
=> SELECT '24:00:01'::time without time zone;
ERROR: date/time field value out of range: "24:00:01"
LINE 1: SELECT '24:00:01'::time without time zone;
You're creating a full DateTime:
.toDateTimeToday()
http://joda-time.sourceforge.net/api-release/org/joda/time/TimeOfDay.html#toDateTimeToday%28%29
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.
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)