I think this question is simple really but I wasn't able to find an answer for it.
In Knex i could set a timestamp in my database with knex.fn.now()
However now I have a need to set a date 30 days after now is this as simple as knex.fn.now() + 30 work or is there another trick?
Any help is appreciated even a link to a different source.
Thank you in advance
knex.fn.now() will execute CURRENT_TIMESTAMP function on the db, which returns timestamp in ms from 1/1/1970.
You can use a db built in method for calculating future dates.
In MySQL this method calls date_add.
SELECT date_add(now(), INTERVAL 30 day);
With Knex you will need to use the raw method.
knex.select(knex.raw('date_add(?, INTERVAL ? day)', [knex.fn.now(), 30]));
Edit:
In postgress, this query will look like:
SELECT CURRENT_DATE + INTERVAL '1 day';
so, in Knex it will be:
knex.select(knex.raw(`? + INTERVAL '? day'`, [knex.fn.now(), 30]));
Thank you for the previous answer, but that Postgresql example didn't work for me.
When I tried knex.raw(`? + INTERVAL '? day'`, [knex.fn.now(), 30]), I got an error "could not determine data type of parameter"
This worked:
knex.raw(`? + ?::INTERVAL`, [knex.fn.now(), '30 day'])
Related
I am trying to use zenpy to get information on tickets created or modified in the last week. This is the code I am using:
stream_status = False #Exit condition
while(stream_status==False):
print(start_date)
all_tickets = zendesk.tickets.incremental(start_time=start_date, include=['users','organizations'])
print(len(all_tickets))
print(all_tickets.end_time)
for ticket in all_tickets:
#grab ticket fields and store them in a Dataframe
df.loc[len(df)] = [ticket_id,created_at,requester,organization,product,subject,assignee,status,priority,opened_at,opened_by,solved_at,solved_by,closed_at,closed_by]
count +=1
print(count,ticket_id)
start_date = all_tickets.end_time
stream_status = all_tickets.end_of_stream
print(start_date,stream_status)
today = datetime.now().strftime("%Y%m%d%H%M")
df.to_excel('Ticket_report{0}.xlsx'.format(today))
Now there are several issues here. The date is calculated correctly and it's indeed 7 days ago. But the tickets I am getting are going back to at least April and they were definitely not been modified since. I stopped it at this point cause we have thousands of tickets.
Also, the incremental method returns a max of 1000 ticket objects, but even after 1000 the loop doesn't seem to restart (print statement at the end doesn't trigger). I am not sure I am using the stream_status flag correctly. Any advice is more than welcome. Thank you!
Zenpy documentation on incremental can be found here: http://docs.facetoe.com.au/zenpy.html#incremental-exports
It was an API issue after all.
For anyone facing similar issues, turns out that the start date is compared against the generated_timestamp instead of the updated_at or created_at fields. Updated_at holds the last action that generated a ticket event(e.g. change) but generated_timestamp is updated every time the ticket is affected even from the system. That leads to grabbing tickets updated or created before the input date. A solution for that is to filter out the results after the call:
all_tickets = zendesk_client.incremental(start_time=start_date)
accurate_tickets = [ticket for ticket in all tickets if parser.parse(ticket.updated_at) > start_date]
Not very sure why they designed the API like this, seems a bit wrong, but that's how it works unfortunately.
Source: https://developer.zendesk.com/documentation/ticketing/managing-tickets/using-the-incremental-export-api/#excluding-system-updated-tickets-time-based-exports
UPDATE 2
Using the suggestions from #Bergi, I added a db execution helper to set the timezone before executing the query. This allows me to control the timezone based on the logged in user's preferences.
async function execWithTZ(sql, params, timezone) {
const client = await this.pool.connect();
await client.query<any>(`SET TIMEZONE TO '${timezone}'`, []);
return client.query<any>(sql, params);
}
const result = await execWithTZ('SELECT ...', [], 'Australia/Sydney');
QUESTION
I am trying to get Postgresql to return the day of the week of a specific date in a view. I later use this to display values by day.
The data is in a table with a column named updated which is a timestamptz field.
When running the following query using DBeaver SQL client against a PostgreSQL 12 database I get the values as I expect, with records updated on Thursday local time (just after midnight) showing up as Thursday
SELECT
count(v.id) AS count,
btrim(to_char(v.updated, 'DAY'::text)) AS day,
date_trunc('DAY'::text, v.updated) AS "updatedDay"
FROM table v
GROUP BY (to_char(v.updated, 'DAY'::text)), (date_trunc('DAY'::text, v.updated))
I put this in a view and when I query this view using node-postgres the counts are for the previous day (Wednesday), which I presume is because the database thinks it should interpret the dates in the UTC timezone.
To further prove the point, when I change the above query to use DAYTZ instead of just DAY in DBeaver I get THURSDAYAEST but in nodejs as result I get WEDNESDAYUTC
Changing all my dates to be without timezone and forcing everything to UTC on the way in is not an option for me.
How can I make node-postgres tell the database what timezone I want these dates interpreted as so that I can get the correct day?
UPDATE 1
I managed to get PostgreSQL to return the correct values to postgres node by setting the database user's timezone.
ALTER ROLE visuo_ingest SET TIMEZONE TO 'Australia/Sydney';
Now the counts for things that happened on Thursday Sydney time is counted for Thursday and not Wednesday.
Still interested in a way to do this on the connection rather than the database user level.
Still interested in a way to do this on the connection rather than the database user level.
You already found the right setting, there's no reason to alter it on a role only. You can also change the setting in a client session by running the SET command
SET TIMEZONE TO 'Australia/Sydney';
Just put that in a pgClient.query("…"); right after connecting the client.
I am trying to remove timestamp from a data column. I can do that in SQL Server Management Studio doing:
select CAST(GETDATE() as date)
Now, when I try to do the same thing using Nodejs-MSSQL library I get the time stamp as well:
await pool.query(` select CAST(GETDATE() as date)`)
Can someone please explain how this is even possible?
I want to know if there’s a way to insert Data in database in a specific moment,
Exemple:
I want to send a text to the Database in 3 hours => As soon as i click on my button in my client side i want the document to be created in 3 hours.
Is it possible to do something like this ?
you can simply use setTimeOut like this.
let time = 60000 * 60 * 3;
function myFunc(arg) {
console.log(`arg was => ${arg}`);
}
setTimeout(myFunc, time, 'funky');
or use cronjob like this npm https://www.npmjs.com/package/node-cron
I don't think it's a good way to create documents. I don't know your problem, but I would solve it differently.
You could create the document when the button is clicked. But, you'll add a new property in your document like active_at that will hold a date value (timestamp or other). This value will be always current date + 3 hours. In your application, after that, you'll have to select/get documents where active_at is before the current date. This way, you'll have only the documents created at least 3 hours ago.
You can use setTimeout function in nodejs backend:
function myFunc(arg) {
//Insert text to mongodb
}
setTimeout(myFunc, 10800000); //myFunc will be called after 3 hours (10.8000.000 ms)
You can find more detail about setTimeout function here: https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_args
Is there a way to obtain the local timezone from the system (eg:- ubuntu) using nodejs?
I used moment.js to extract the date and time values. But couldn't find a way to extract the timezone as well.
The existing answers will tell you the current timezone offset, but you will have issues if you are comparing historic/future points in time as this will not cater for daylight saving changes.
In many timezones, the offset varies throughout the year and these changes occur at different dates or not at all depending on the latitude. If you only have UTC time and an offset, you can never be sure what the offset will be in that location at various other times during the year.
For example, a UTC+2:00 offset could refer to Barcelona in the summer or Ivory Coast all year round. The 2hr offset will always display the correct time in Ivory Coast but will be 1hr out for half the year in Barcelona.
Check out this great article covering the above.
How do we cater for all these time zone issues? Well, it's pretty simple:
Save all times in UTC
Store the time zone string for where this event occurred
In modern browsers or node.js, you can get the local IANA time zone string like this:
Intl.DateTimeFormat().resolvedOptions().timeZone // eg. 'America/Chicago'
You can then use this timezone string in a library like Luxon to help offset your captured UTC times.
DateTime.fromISO("2017-05-15T09:10:23", { zone: "Europe/Paris" });
It is very simple.
var x = new Date();
var offset= -x.getTimezoneOffset();
console.log((offset>=0?"+":"")+parseInt(offset/60)+":"+String(offset%60).padStart(2, "0"))
And there is nothing else or you can see if momentJS can help you or not.
Note: This answer is outdated, you can suggest to add in it.
It is this easy, no libraries needed:
console.log("test ...")
let d = new Date()
console.log("UTC time " + d)
let ank = d.toLocaleString('en-US', { timeZone: 'America/Anchorage' });
console.log("your time zone " + ank)
How to see the exact time zone names on most servers:
ls /usr/share/zoneinfo
Works flawlessly:
You'll get the correct time-text regardless of daylight savings issues, etc etc.
Handy related mysql tip:
On almost all servers, mysql also needs to know the tz info.
Basically the solution is, on the shell
sudo mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql
.. google more about it.
I solved this using moment.js (http://momentjs.com/docs/)
var moment = require('moment');
var offset = moment().utcOffset();
console.log(''.concat(offset < 0 ? "-" : "+",moment(''.concat(Math.abs(offset/60),Math.abs(offset%60) < 10 ? "0" : "",Math.abs(offset%60)),"hmm").format("HH:mm")));
------Edited--------
I found a better solution using moment.js. Just use moment().format('Z')
which gives the output :
+05:30