I need to obtain current time (from a credible source) using JSON. Precise time is mission-critical in my application so I cannot rely on the time of the device, even if it is only a second or two off.
EDIT: I am not as worried about 'precision' rather just so that several devices running the app have the same time.
As of Jan. 07th 2020 http://worldtimeapi.org/ is working fine. we can get current date and time details for specfic time-zone or ip address easily in either json format or plain text format.
http://worldtimeapi.org/api/timezone/America/Santiago
the above url will give you the current date and time details in json for "America/Santiago".
http://worldtimeapi.org/api/timezone/Asia/Kolkata
the above url will give you the current date and time details in json for "Asia/Kolkata".
Request the current time based on your public IP (as JSON):
$ curl "http://worldtimeapi.org/api/ip"
Note: by default, the API returns JSON. Adding a suffix of .txt to any API URL will return a plain-text response, which may be easier to parse on some systems.
function getTime(zone, success) {
var url = 'http://json-time.appspot.com/time.json?tz=' + zone,
ud = 'json' + (+new Date());
window[ud]= function(o){
success && success(new Date(o.datetime));
};
document.getElementsByTagName('head')[0].appendChild((function(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = url + '&callback=' + ud;
return s;
})());
}
getTime('GMT', function(time){
// This is where you do whatever you want with the time:
alert(time);
});
from here
As of Sept. 12th 2015 http://www.timeapi.org/utc/now.json seems to be working.
{"dateString":"2015-09-12T23:15:56+01:00"}
More information here http://www.timeapi.org. It's hosted on Heroku and the source is on Github.
The worldtimeapi.org is working just fine. If you will be using Javascript:
const zone = 'Europe/Lisbon'
fetch('https://worldtimeapi.org/api/timezone/' + zone)
.then(r => r.json())
.then(r => {
// strip out timezone offset from datetime ISO string
const d = new Date(r.datetime.replace(/[+-]\d\d:\d\d$/, ''))
console.log(`Time now in ${zone}: ${d.getHours()}:${d.getMinutes()}`)
})
Related
I am trying to encrypt 3 different elements into an authentication token for a http headers for an API. This API is built into Google Sheets, and I can't use anything else at the moment.
The authentication token requires 4 parts:
API Key
Timestamp in UTC format
API Action
API Secret Key
In the format of API KEY:TIMESTAMP:API ACTION:API Secret Key
For the purposes of this example, let's say that the
API key is test123,
UTC Date: Thu, 14 Apr 2011 22:44:22 GMT
API action is 'ledger'
API Secret key is UAV213Q
When I tested the example using following format "test123:Thu, 14 Apr 2011 22:44:22 GMT:ledger:UAV213Q" in python I got the result 15594d1f608134cbfa3075ecda4664519cd198738b8f5c3ffa2c95272b854199
This is the python script I used
def sha256():
# tested on Python 3.8.5
from urllib import parse, request
import hashlib
import datetime
from time import strftime, gmtime
# credentials and request params
my_merchant_id = 'apikey'
api_token = 'test123'
api_secret_key = 'UAV213Q'
my_timestamp = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
api_version = 2.9
action_verb = 'ledger'
# set up request params
data = parse.urlencode({'merchantId': my_merchant_id, 'token': api_token,
'version': api_version, 'action': action_verb})
# authentication
sig = api_token + ':' + my_timestamp + ':' + action_verb + ':' + api_secret_key
sig_hash = hashlib.sha256(sig.encode('utf-8')).hexdigest()
my_headers = {'x-ShareASale-Date': my_timestamp,
'x-ShareASale-Authentication': sig_hash}
print(sig_hash)
I've tried using solutions from the following other StackOverFlow questions
How do I get Google Apps Script to do SHA-256 encryption?, sha3-256 of a cell text in Google Spreadsheet, all the suggestions.
However, I keep getting the error message "This function is not allowed to reference a cell with NOW(), RAND(), or RANDBETWEEN()."
I have tried referencing a cell that is indirectly references the NOW() by having NOW() in A1 and having B1 =A1, I have even tried to convert it to text by using the TEXT().
The API key needs to have the timestamp to function. I was thinking about having that calculated in the App script itself, since it is a known constant. For example within the encryption script it would hardcode the api token, call the timestamp in utc format and hardcode the api secret key in the correct format and the maybe just the function to add the action so I can make change that so it would be sha256(ledger) and it would incorporate that into the encryption
How about this answer?
Modification points:
When I saw your python script, I confirmed that the specification shown in your question is different from that of the python script.
It seems that Thu, 14 Apr 2011 22:44:22 GMT is Thu, 14 Apr 2011 22:44:22 +0000
It seems that it is required to use "SHA_256" of the digest.
Sample script:
When your python script is converted to Google Apps Script, it becomes as follows. Please copy and paste it to the script editor and run the function myFunction at the script editor. By this, you can see the result value at the log.
function myFunction() {
const api_token = 'test123';
const api_secret_key = 'UAV213Q';
const my_timestamp = 'Thu, 14 Apr 2011 22:44:22 +0000';
const action_verb = 'ledger';
const value = `${api_token}:${my_timestamp}:${action_verb}:${api_secret_key}`;
const bytes = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, value);
const res = bytes.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
console.log(res)
}
Result:
When test123:Thu, 14 Apr 2011 22:44:22 +0000:ledger:UAV213Q is used for above Google Apps Script and your python script, both results are the same as follows.
8c3a6873fe71c402dc1e3ca7bc828712e3dfb7a66ed09feeeca2152dd809df81
Reference:
computeDigest(algorithm, value)
Added:
Answer for additional question 1:
When you want to retrieve the date string like Thu, 14 Apr 2011 22:44:22 +0000, please use the following script.
const my_timestamp = new Date().toUTCString().replace("GMT", "+0000");
Answer for additional question 2:
When you want to retrieve the value as the upper case, please use the following script. But when I tested your python script, the result value is the lower case. So please be careful this.
function myFunction() {
const api_token = 'test123';
const api_secret_key = 'UAV213Q';
const my_timestamp = 'Thu, 14 Apr 2011 22:44:22 +0000';
const action_verb = 'ledger';
const value = `${api_token}:${my_timestamp}:${action_verb}:${api_secret_key}`;
const bytes = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, value);
const res = bytes.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('').toUpperCase();
console.log(res)
}
In this case, 8C3A6873FE71C402DC1E3CA7BC828712E3DFB7A66ED09FEEECA2152DD809DF81 is obtained.
References:
toUTCString()
toUpperCase()
I am using AngularJS client-side application and working with date and time. My problem is that local system date anyone can change, to protect this I want to use server date without any get or post request. Is there any way to get server date using JavaScript?
If you are running JavaScript at the client-side, the only way to find the server time is asking the server what is the current time. There is no magic here. You need to make a request to the server.
Options:
Use AJAX or Fetch.
If the HTML page is rendered in the server, you can write the current time during the page render and send it to client.
Please, note that it is not possible to have a precise time of the server due to network delays, but you can get pretty close using the code from this answer (modified):
var offset = 0;
function calcOffset() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "https://stackoverflow.com/", false);
xmlhttp.send();
var dateStr = xmlhttp.getResponseHeader('Date');
var serverTimeMillisGMT = Date.parse(new Date(Date.parse(dateStr)).toUTCString());
var localMillisUTC = Date.parse(new Date().toUTCString());
offset = serverTimeMillisGMT - localMillisUTC;
}
function getServerTime() {
var date = new Date();
date.setTime(date.getTime() + offset);
return date;
}
I have been looking for an example of how to call a trusted function in acroforms and havent found any. I am trying to build a form for my company that will allow users to click a button and automatically have the form save to a folder on our server (eg: //SERVER1/Forms/). I found this code to test with and placed it in C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\Javascripts
//SaveAs Function1
var date = new Date();
var day = date.getDate();
var month = date.getMonth()+1;
var year = date.getFullYear();
var dateSigned = String(month) + String(day) + String(year);
var mySaveDoc = app.trustedFunction(function(doc,fileNamÂe){
app.beginPriv();
var myPath = "C/test/" + fileName + "Agreement " + dateSigned + ".pdf";
//saveAs is the only privileged code that needs to be enclosed
doc.saveAs({cPath: myPath, bCopy: true, bPromptToOverwrite: false});
//doc.close();
app.endPriv();
});
Any help on making this work is greatly appreciated!!
I think the location of the application level script is correct; check whether you have other files in that folder; one of them would be a precompiled one, coming from Adobe.
Now, for calling the trusted function, well…, call it as you would call any other function:
mySaveDoc(this, fileName) ;
and that should do it.
However, there are a few issues I don't like that much in the application-level script:
The dateSigned variable and its bits and pieces will be defined and initialized when the application starts, and then keep their value. In other words, if you keep Reader running all the time, the date will not be updated. To get the current date all the time, you'd have to initialize the dateSigned variable within the function. AND, as you are in Acrobat JavaScript, you can use the util object for assembling the string.
Your script would then look like this:
var mySaveDoc = app.trustedFunction(function(doc, fileName){
app.beginPriv() ;
var dateSigned = util.printd("MMDDYYYY", new Date() ;
var myPath = "/C/test" + filename + "Agreement " + dateSigned + ".pdf" ;
doc.saveAs({cPath: myPath, bCopy: true, bPromptToOverwrite: false}) ;
app.endPriv() ;
}) ;
Note that there is als a slash at the beginning of the path (although I may be wrong on that; as I don't have access to a Windows machine, I can not verify it; if someone else would use Acrobat, open any file, and then run this.path() from the Console, then he could confirm the slash (or not)).
I try to schedule a script using the 'Scheduled Tasks' in ML8. The documentation explains this a bit but only for xQuery.
Now I have a JavaScript file I'd like to schedule.
The error in the log file:
2015-06-23 19:11:00.416 Notice: TaskServer: XDMP-NOEXECUTE: Document is not of executable mimetype. URI: /scheduled/cleanData.js
2015-06-23 19:11:00.416 Notice: TaskServer: in /scheduled/cleanData.js [1.0-ml]
My script:
/* Scheduled script to delete old data */
var now = new Date();
var yearBack = now.setDate(now.getDate() - 65);
var date = new Date(yearBack);
var b = cts.jsonPropertyRangeQuery("Dtm", "<", date);
var c = fn.subsequence(cts.uris("", [], b), 1, 10);
while (true) {
var uri = c.next();
if (uri.done == true){
break;
}
xdmp.log(uri.value, "info"); // log for testing
}
Try the *.sjs extension (Server-side JavaScript).
The *.js extension can be used for static JavaScript resources to return to the client instead of executed on the server.
Hoping that helps,
I believe that ehennum found the issue for you (the extension - which is what the mime-type error is complaining about.
However, on the same subject, not all items in ML work quite as you would expect for Serverside Javascript. For example, using sjs as a target of a trigger is (or recently) did not work. So for things like that, it is also possible to wrap the sjs call inside of xqy using xdmp-invoke.
I have a set of links on a web page that link to PDF forms and .doc forms. These files are not stored in a database, simply stored as they are, locally on the server. Is it possible to retrieve the last modified date of a PDF or DOC file using Javascript? I don't have any specific need to use Javascript, but it is preferable.
UPDATE: Now that I realize that Javascript can't access the filesystem, is there an alternative method?
If it's on the same server as your calling function you can use XMLHttpRequest-
This example is not asynchronous, but you can make it so if you wish.
function fetchHeader(url, wch) {
try {
var req=new XMLHttpRequest();
req.open("HEAD", url, false);
req.send(null);
if(req.status== 200){
return req.getResponseHeader(wch);
}
else return false;
} catch(er) {
return er.message;
}
}
alert(fetchHeader(location.href,'Last-Modified'));
This seems to be useful, and works for me - giving you the 'local' date
document.lastModified
Compared to the above selection of req.getResponseHeader() it's one less round trip/http call.
Using the modern fetch method:
var lastMod = null;
fetch(xmlPath).then(r => {
lastMod = r.headers.get('Last-Modified');
return r.text();
})
File.lastModified
You can use the File.lastModified property to obtain the last modified date of a file as the number of milliseconds since the Unix epoch.
Example:
const file = document.getElementById('input').files[0];
const lastModifiedDate = new Date(file.lastModified);
console.log(`Last Modified Date: ${lastModifiedDate}`);
If an interface is exposed through HTTP, you can. Another way of saying: expose a WebService end-point to gain access to this information.
Of course, you can't have direct access to the filesystem for security reasons.
Formatting #FutureBoy's answer as a full function and adding a HEAD method and date conversion, the code would appear as follows.
function fetchLastModified(url, callback) {
fetch(url, {method: "HEAD"})
.then(r => {callback(new Date(r.headers.get('Last-Modified')))});
}
No, it's not. You can't access the file system through JavaScript