How to convert "string" to "timestamp without time zone" - javascript

I am new to Postgresql and I am using WCF services.
Here is my code snippet:
$.ajax({
url: '../Services/AuctionEntryServices.svc/InsertAuctionDetails',
data: JSON.stringify({ "objAuctionEntryEntity": {
"AuctionNO": '',
"AuctionDate": $('[Id$="lblAuctionDateVal"]').text(),
"TraderID": $('[Id$="ddlTraderName"] option:selected').val(),
"Grade": $('[Id$="ddlGrade"] option:selected').val(),
"Varity": $('[Id$="ddlVarity"] option:selected').val(),
"QuntityInAuction": $('#txtQuantityForAuction').val(),
"AuctionRate": $('#txtAuctionRate').val(),
"BrokerID": a[0],
"IsSold": $('#chlIsSold').is(':checked'),
"CreatedBy": $.parseJSON(GetCookie('Admin_User_In_Mandi')).UserID,
"UpdatedBy": $.parseJSON(GetCookie('Admin_User_In_Mandi')).UserID,
"CreationDate": GetCurrentDate().toMSJSON(),
"IsActive": true,
"AuctionTransaction": arrAuctionTransaction,
"MandiID": $.parseJSON(GetCookie('Admin_User_In_Mandi')).MandiID,
"FarmerID": _ownerid,
"AuctionNO": _auctionno,
"AmmanatPattiID": _ammantpattiid,
"ToTraderID": b[0],
"ToTraderName": $('#txtOtherBuyerNameEN').val(),
"ToTraderName_HI": $('#txtOtherBuyerNameHI').val()
}
}),
type: 'POST',
contentType: 'application/json',
dataType: 'json'
});
Here:
$('[Id$="lblAuctionDateVal"]').text() = "20/8/2013 14:52:49"
And my data type for this field is timestamp without time zone.
How to convert this string to timestamp without time zone data type?

String representation of a timestamp (= timestamp without time zone) depends on your locale settings. Therefore, to avoid ambiguities leading to data errors or Postgres coughing up an exception, you have two options:
1.) Use ISO 8601 format, which works the same with any locale or DateStyle setting:
'2013-08-20 14:52:49'
You may have to cast the string literal explicitly where the data type cannot be derived from context, depending on the use case:
'2013-08-20 14:52:49'::timestamp
2.) Convert the string to timestamp using to_timestamp() with a matching template pattern:
to_timestamp('20/8/2013 14:52:49', 'DD/MM/YYYY hh24:mi:ss')
This returns timestamptz, assuming the current timezone setting. Typically (like in an assigmment) the type is coerced accordingly. For timestamp, this means that the time offset is truncated and you get the expected value.
Again, if the target type cannot be derived from context, you may have to cast explicitly:
to_timestamp('20/8/2013 14:52:49', 'DD/MM/YYYY hh24:mi:ss')::timestamp
Since that simply strips the time offset, it results in the expected value. Or use the AT TIME ZONE construct with a time zone of your choosing:
to_timestamp('20/8/2013 14:52:49', 'DD/MM/YYYY hh24:mi:ss') AT TIME ZONE 'UTC'
While the target time zone is the same as your current timezone setting, no transformation takes place. Else the resulting timestamp is transposed accordingly. Further reading:
Ignoring time zones altogether in Rails and PostgreSQL

To convert a string into a timestamp without timezone, for Postgresql, I use the above
SELECT to_timestamp('23-11-1986 09:30:00', 'DD-MM-YYYY hh24:mi:ss')::timestamp without time zone;

Related

converting time to local timezone not working with moment.js in React

I am converting a timestamp on a DB object using moment:
{moment(comment.created_at).local(true).format('h:mm a')}
My time is outputting in UTC time because that is how it gets created in my DB.
So I am seeing '6:45 PM' for example, when I want to see the time in MY timezone (EST) or the user's relative timezone. According to the moment docs local() will convert to your current timezone? Calling the local() method as shown in my code aboven does not change the time zone. Am I using this incorrectly?
My DB object
{
client_id: 24
created_at: "2022-02-11 17:41:39.330443"
id: 22
report: "sfsf"
report_category: "Client Assigned"
volunteer_id: 23
}
Your database is storing the date without an offset indicator. This means that moment cannot automatically determine the timezone. As per the documentation on parsing dates:
moment(...) is local mode. Ambiguous input (without offset) is assumed to be local time. Unambiguous input (with offset) is adjusted to local time. * moment.utc(...) is utc mode. Ambiguous input is assumed to be UTC.
So if you know your input is UTC and you know it won't have an offset indicator, use moment.utc() instead of moment().
Furthermore, you don't want to use local(true), since passing in "true" will only change the timezone on the object without changing the time (see the documentation). So you're left with:
{moment.utc(comment.created_at).local().format('h:mm a')}
I converted your DB timestamp into ISO format and then passed into your implementation
let t = "2022-02-11 17:41:39.330443"
let utcISOTimestamp = moment.utc(t).toDate()
console.log(utcISOTimestamp)
//let res = moment(utcISOTimestamp).local(true).format('h:mm a');
let res = moment(moment.utc(t).toDate()).local(true).format('h:mm a');
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Try using:
moment.utc('2022-02-11 17:41:39').local().format('YYYY-MM-DD HH:mm:ss')

LuxonJs formating date

I am getting from the DB a date in UTC
example: 2021-06-14T16:00:30.000Z
The idea is to change this date to LOCAL date so the output needs to be
2021-06-14T12:00:30.000Z
The problem is that doesn't matter what methods of Luxon use, I don't get that specific format (YYYY-mm-ddTHH:mm:ssZ)
How can I do this?
this piece of code is where I will put the Date getting from the DB, just need that format
const d = DateTime.fromISO('2021-06-14T16:00:30.000Z', { zone: 'America/Santiago' });
The ISO format is basically [date]T[localtime][offset]. The offset tells you with what UTC offset the local time is expressed. It could be like -04:00 (four hours behind UTC) or it could be "Z", which means +00:00, and generally implies not just the offset, but that the zone is UTC.
So the problem is that with a "Z" on it, your expected string specifically indicates that it's not a local time, even though you've explicitly converted your DB's UTC time to a Santiago local time. In other words, the string you want specifies a different time than the DateTime object represents. That's why Luxon doesn't have a convenient method to do what you want; it doesn't really make sense.
So here are a few options:
d.toISO() //=> "2021-06-14T12:00:30.000-04:00", probably what you want
d.toISO({ includeOffset: false }) //=> "2021-06-14T12:00:30.000", if you don't want the offset
d.toUTC().toISO() // "2021-06-14T16:00:30.000Z", back to UTC
If you really want the local time but with a Z, you can accomplish this, but note that anything parsing it will interpret it as expressing a different time (not a different local time, but a different millisecond in the history of the world) than the time in your DB, off by four hours:
d.toISO({ includeOffset: false }) + "Z"; // => "2021-06-14T12:00:30.000Z"
// OR
d.setZone("utc", { keepLocalTime: true }).toISO() // => "2021-06-14T12:00:30.000Z"

Wrong date returned by JS when parsing ISO string sent by Dart

In my flutter app, I have a funtion that sends an ISO date string to a node.js rest API. However, when the date is parsed with in the js Date object, it returns a different date. I've also tried to send it in other formats like .toLocal() and .toUtc() with the same result.
Flutter (Dart)
///
/// SEND DATE TO NODE.JS ENDPOINT
///
void sendDate() async {
DateTime date = new DateTime(2020, 1, 1);
http.Response response = await http.post(
Uri.encodeFull('${config.domain}/sendDate'),
headers: { "Content-type" : "application/json"},
body: jsonEncode({"date": date.toIso8601String()})
);
print("Sent date");
print(date.toIso8601String());
print("Received date");
print(response.body);
}
Output
I/flutter (14203): Sent date
I/flutter (14203): "2020-01-01 00:00:00.000"
I/flutter (14203): Received date
I/flutter (14203): "2019-12-31T23:00:00.000Z"
Node.js (Javascript)
api.post('/sendDate',(req,res)=>{
console.log("Sent date")
console.log(req.body.date)
const date = new Date(req.body.date);
console.log("Parsed date");
console.log(date);
res.send(date);
});
Output
Sent date
2020-01-01T00:00:00.000
Parsed date
2019-12-31T23:00:00.000Z
As shown above, the date parsed by Javascript is one day less than the date sent by flutter.
P.S: As stated above, i've sent it in other formates like locale and UTC. Also no timezone configuration has been added.
EDIT: The date returned is actually an hour less. i.e sending DateTime(2020, 1, 1, [2]), will return DateTime(2020, 1, 1, [1]).
According to JavaScript's only in-spec date/time format, the string "2020-01-01 00:00:00.000" is invalid (it should have a T, not a space, between the date and time). (Indeed, according to Wikipedia, a space isn't valid in ISO-8601, either, though it's a common implementation extension.) But V8 (the JavaScript engine used by Node.js) is okay with that, it'll handle a space instead.
Additionally, the string has no timezone information, so this part of the date/time string parsing rules kicks in:
When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
So you appear to be in a timezone that's at GMT+0100. Midnight on Jan 1st in Europe, West Africa, etc. (GMT+0100) is 11 p.m. Dec 31st UTC / GMT.
If you want that date/time interpreted as UTC, you need to add a Z to the end before parsing. To be completely within spec, replace the space with a T as well.

Localize UTC time/date

i have a timestamp which comes from server (utc). I now want to transform this timestamp to my local time.
Transform UTC:
2016-08-11 12:19:14
To local time:
2016-08-11 14:19:14
This is what i have used:
localizeTime = function (timeToLocalize = "2016-08-11 12:19:14") {
return moment(timeToLocalize).locale(deviceLocale = "de").format('LLL');
};
I am working with react-native and moment.js
If the input time is UTC, and you don't have anything in the string to indicate such, then you need to parse it with moment.utc instead of just with moment. You can then convert it to local time with the local function.
moment.utc("2016-08-11 12:19:14").local().format("YYYY-MM-DD HH:mm:ss")
You don't need to involve locales (like de) unless you really want a locale-specific string format. Locale has to do with language and culture, not with time zones. "local" != "locale"

Need to read epoch time in certain timezone and then convert it to user timezone

I have 2 webapps, 1 of them on cloud is "master", to which I need to match dates in the 2nd webapp "child".
Master (1st webapp, cloud) is showing date in IST, Asia/Kolkata which it reads from sql machine sitting in EST timezone.
Child (2nd webapp) reads it's data from Elasticsearch where a java feeder picks up the sql data and pushes it to Elasticsearch as it is, without any conversion.
When I try to read this Elasticsearch data in my webapp (child)
...
{
"_index": "log_event_2016-05-05",
"_type": "log_event",
"_id": "65708004",
"_score": null,
"_source": {
"task_name": "kn_cvs_test",
"task_start_time": "2016-05-05T19:05:05.000-07:00",
"task_end_time": "2016-05-05T19:05:06.000-07:00",
"started_by": "Schedule \"10Minutes\"",
"log_datetime": 1462475106000,
"dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
},
"sort": [
1462475106000
]
}, {
"_index": "log_event_2016-05-05",
"_type": "log_event",
"_id": "65708005",
"_score": null,
"_source": {
"task_name": "kn_cvs_test",
"task_start_time": "2016-05-05T18:55:08.000-07:00",
"task_end_time": "2016-05-05T18:55:11.000-07:00",
"started_by": "Schedule \"10Minutes\"",
"log_datetime": 1462474511000,
"dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
},
"sort": [
1462474511000
]
}
...
the dates in my webapp and the cloud does not match. Please correct me if I am wrong. Since Sql is storing dates in EST, "America/New_York", Momentjs should 1st read the data = 1462475106000 in EST and then apply the user timezone which is IST, "Asia/Kolkata". Is this correct?
//Timestamp column in table
//data = 1462475106000
$scope.getMeData = function(data) {
var dFormat = "YYYY-MM-DD hh:mm:ss A";
moment.tz.setDefault("America/New_York");
return moment.tz(data, "Asia/Kolkata").format(dFormat);
}
Note: 1462475106000 is the 1st entry in both table
I am putting up a plunker here.
Please help me figure out what could be going wrong and how can I match dates in both the webapps (taking cloud as reference).
Update
Java feeder runs a sql query to fetch all the needed columns. Here is how log_datetime is fetched. Is this the correct way to fetch?
(task_end_time - to_date('1-1-1970 00:00:00','MM-DD-YYYY HH24:Mi:SS'))*24*3600*1000 AS "log_datetime"
So I am assuming when it fetches data Daylight saving information is not considered and I am missing out this info too. So on UI side i'll check for isDST() and do a +5:00 hrs or +4:00 hrs depending on it, as date in sql is stored in America/New_York. Plunker with UI fix
There's only one Epoch time anywhere at a time. It's an absolute value.
A value that approximates the number of seconds that have elapsed since the Epoch. A Coordinated Universal Time name (specified in terms of seconds (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time represented as seconds since the Epoch, according to the expression below.
Ref http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15
Epoch time is measured from the 01-01-1970 00:00:00 UTC. That's an absolute instant in time, it's not relative to timezone as the timezone UTC is in definition of the epoch.
Whenever you see a number for a date such as your example 1462475106000, it should be assumed to be in UTC/GMT. It's not a timezone specific value. Since the time is Unix based number, by epoch definition it is time passed since epoch (in UTC), making it absolute time.
(01-01-1970 00:00:00 UTC)(epoch) + 1462475106000 = Time in UTC
A date in string is a different matter entirely. It should include the timezone offset with the date part. Date part would be considered to be timezone specific value. Adding timezone offset to it would convert it to absolute value in UTC. Without timezone information a string date has no absolute value (Point in time).
2016-05-05T18:55:08.000-07:00 = (2016-05-05T18:55:08.000) + (07:00 hrs) UTC
or
date + timezone offset = date - offset hrs UTC
Databases don't store dates in any timzzone. They store absolute Unix time value. Timezone setting in databases are set so that the output of the query in string is shown in that timezone format. This setting only specifies the output date format not the value. Since the value is absolute it's same timezone independent.
This setting also helps database in determining the timezone of the date value that a user inserts if he misses the timezone offset. If the user tries to insert a string in date column without timezone database would try to default the string to database timezone setting.
So 1462475106000 is a value in UTC as it's Unix time. It's not in EST.
If you need date to be in EST then use the date in string format not in number format as number format is always UTC.
moment.tz.setDefault("America/New_York");//sets the output date format in EST
Above code will have no effect as it's overwritten by moment.tz(data, "Asia/Kolkata")
Now considering the first entry in the first screenshot.
2016-05-06T04:35:06.000+5:30 (IST) = 2016-05-05T11:05:06.000-00:00 (UTC)
Comparing it with the second screenshot, since the time difference between the two is 4 hours, second one should be in +01:30 timezone, if they both are the same values in absolute time.
2016-05-06T12:35:06.000+1:30 = 2016-05-05T11:05:06.000-00:00 (UTC)
However in the child the value is
2016-05-05T19:05:06.000-07:00 = 2016-05-06T02:05:06.000-00:00 (UTC)
Which is not the same value as both above. Interesting fact is that only date part in the child 2016-05-05T19:05:06.000 when added IST offset +05:30would become the date part in second screenshot.
2016-05-06T12:35:06.00 - 2016-05-05T19:05:06.000 = 5:30 (IST offset)
Leaving that aside your Java feeder code to ElasticSearch is probably culprit here.
It's not writing the correct date-timezone combination to ElasticSearch. Try using the overloaded method getDate()
getDate(int columnIndex, Calendar cal)
in JDBC.
Sometimes JDBC driver misses timezone information, causing the date to be stored in default database timezone, using Calendar would cure that.
Same goes for writing dates as well.
void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
You just need to convert dates from America/New York to Asia/Kolkata (Asia/Calcutta)?
var newYork = moment.tz("date-from-database", "America/New_York");
var calcutta = newYork.clone().tz("Asia/Calcutta");
Example
var newYork = moment.tz("2016-05-06 12:00:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
var Kolkata = newYork.clone().tz("Asia/Kolkata");
var dFormat = "YYYY-MM-DD hh:mm:ss A";
console.log(newYork.format(dFormat),losAngeles.format(dFormat),london.format(dFormat),Kolkata.format(dFormat));
Fiddle

Categories

Resources