This is my first attempt at script. I'm pretty familiar with VBA. I have a date in A1 in the "Day" Sheet. I have a range of dates in column A on the "Monthly" sheet. I'm trying to find todays date on monthly sheet (from the variable on "Day" sheet) and paste the data there. I can't get past this first step of finding the date row. Basically the manager will have a form ("Day" Sheet) and when he hits the save button it will enter the data on the "Monthly" Sheet and it will clear the form. At the bottom I showed the execution log and it says -1.0 for the Index. Seems like it should say 2.0. Any help is much appreciated!
function moveValuesOnly () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getSheetByName("Day");
var reportSheet = ss.getSheetByName("Monthly");
var todayDate = activeSheet.getRange("A1").getDisplayValue();
var lookupRangeValues = reportSheet.getRange(2,1,32,1).getDisplayValues();
var index = lookupRangeValues.indexOf(todayDate);
/*
//cash on hand
activeSheet.getRange("I2").copyTo(reportSheet.getRange("C" & index),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
//POS Readout
activeSheet.getRange("B3").copyTo(reportSheet.getRange("B" & index),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
//Waste or free pizza
activeSheet.getRange("B5").copyTo(reportSheet.getRange("N" & index),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
//Dough made
activeSheet.getRange("B6").copyTo(reportSheet.getRange("L" & index),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
//Total expenses itemized
activeSheet.getRange("A10:G15").copyTo(reportSheet.getRange("I" & index),SpreadsheetApp.CopyPasteType.PASTE_VALUES,false);
*/
Logger.log(todayDate);
Logger.log(lookupRangeValues);
Logger.log(index);
}
10:47:56 PM Notice Execution started
10:47:57 PM Info 6/3
10:47:57 PM Info [[6/1], [6/2], [6/3], [6/4], [6/5], [6/6], [6/7], [6/8], [6/9], [6/10], [6/11], [6/12], [6/13], [6/14], [6/15], [6/16], [6/17], [6/18], [6/19], [6/20], [6/21], [6/22], [6/23], [6/24], [6/25], [6/26], [6/27], [6/28], [6/29], [6/30], [], []]
10:47:57 PM Info -1.0 //I believe this should be 2.0?
10:47:58 PM Notice Execution completed
-1.0 index means that the todayDate was not found on your lookupRangeValues. This is because lookupRangeValues is basically a 2d array and indexOf() is not applicable here. You should create a loop to find the index/row of todayDate. With this, you can replace your line of code with indexOf() to this loop:
for(var row in lookupRangeValues){
if(lookupRangeValues[row][0]==todayDate){
var index = row;
break;
}
}
Related
Hi I need help with this:
I am working on a macro for which I need to get the value of a cell that has the TODAY() formula in it. My spreadsheet is displaying CET accordingly to my location.
When I do:
var today = sheet.getRange('B1').getValues().flat();
Logger.log(today);
I get:
[Wed Feb 24 18:00:00 GMT-05:00 2021]
On the spreadsheet I see 25.02.2021 11:36 (CET), and in Apps Script, it says current EST should be 25.02.2021 05:36. The date is completely off.
Entire code:
function PrepareColumn() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('TheSheetName');
var dateRange = sheet.getRange(2, 1, 1, 15).getValues().flat();
var today = sheet.getRange('B1').getValues().flat();
Logger.log(today);
}
Two modification points:
Use getDisplayValue to get the value that is displayed in the sheet.
For today you are fetching a single cell, you don't need getValues and then flat.
Replace:
var today = sheet.getRange('B1').getValues().flat();
to:
var today = sheet.getRange('B1').getDisplayValue();
and maybe you want to do the same for dateRange:
var dateRange = sheet.getRange(2, 1, 1, 15).getDisplayValues().flat();
I need to test an agenda and I need getting the actual date and current hour to assert with the agenda values.
This not works:
var d = new Date();
expect(day.getText()).toEqual(d.getDate());
You can get current hour using JavaScript inbuilt getHours() method. Here's its usage -
var cTime = Date().getHours();
or
var d = new Date();
var cTime = d.getHours(); //prints the current hour only
And you can get the actual date using getDate() method which prints a string of values related to current date and time. Sample format: Fri Nov 20 2015 20:24:38 GMT+0530 (IST). Hope it helps
I am using a datepicker in a modal window in my Bootstrap application. I am using the original Datepicker from Stefan Petre. I built it where it works in a desktop and mobile using a mouse and it works fine.
Recently I had a user request to allow it to also work with a keyboard. I removed the readonly property to allow the user to enter a date in the input field. The date-format is set to 'mm/dd/yyyy'.
When I enter a date like today for example like this "12/11/13" then it will default to 1913. This isn't a huge deal as I could just train the users to use 4 digits, but I would rather just have it default to this century.
Note: This only seems to happen for the date-format with a 4 digit year. This also seems to happen in the same manner in the newer forks of Stefan's code.
Note: I am using Bootstrap 2.0.4. I am testing with Firefox.
Here is what it looks like:
In JavaScript, set the datepicker's assumeNearbyYear attribute to true, like this:
$("#dp").datepicker({
assumeNearbyYear: true
});
This happens because the Bootstrap datepicker is using JavaScript Date objects. When you create a new Date object and pass in a two digit year it will output 1900+year (see Why does Javascript evaluate a 2-digit year of 00 as 1900 instead of 2000?)
You could try to tweak the datepicker source code, but that might be too complicated.
From what I can see on http://www.eyecon.ro/bootstrap-datepicker/ there is no option to set a range for the selectable dates, but you could change the format to use two digit years.
On your screenshot I can see, that you are using the datepicker for "Arrival Date" which I assume is in the future. On the website there is an example on how to disable dates in the past.
I hope that helps.
UPDATE
I have written an event handler for your problem which should do the trick.
Javascript on http://jsfiddle.net/pCYbd/1/
$("#dp").datepicker();
$("#dp").on("keyup", function(e) {
var date, day, month, newYear, value, year;
value = e.target.value;
if (value.search(/(.*)\/(.*)\/(.*)/) !== -1) {
date = e.target.value.split("/");
month = date[0];
day = date[1];
year = date[2];
if (year === "") {
year = "0";
}
if (year.length < 4) {
newYear = String(2000 + parseInt(year));
$(this).datepicker("setValue", "" + month + "/" + day + "/" + newYear);
if (year === "0") {
year = "";
}
return $(this).val("" + month + "/" + day + "/" + year);
}
}
});
CoffeeScript on http://jsfiddle.net/pCYbd/2/
$("#dp").datepicker()
$("#dp").on "keyup", (e) ->
value = e.target.value
if value.search(/(.*)\/(.*)\/(.*)/) != -1
date = value.split("/")
month = date[0]
day = date[1]
year = date[2]
year = "0" if year == ""
if year.length < 4
newYear = String(2000 + parseInt(year))
$(#).datepicker("setValue", "#{month}/#{day}/#{newYear}")
year = "" if year == "0"
$(#).val("#{month}/#{day}/#{year}")
My JavaScript skills are not the best, but this should work.
Updating bootstrap-datepicker.js as shown in this post solved it for me https://github.com/eternicode/bootstrap-datepicker/pull/1461/commits/2ea16adad27cbc4d4dfa20b924addfb480e5b036
yyyy: function(d,v){
if (format.parts.indexOf('yyyy') > -1 && v < 1000) v = 2000+v; // this line ***
return d.setUTCFullYear(v);
},
I'm using bootstrap-datepicker v1.5.1 and if you look around line 1741 where it does the year mapping, you will notice this:
yyyy: function (d, v) {
return d.setUTCFullYear(v);
},
yy: function (d, v) {
return d.setUTCFullYear(2000 + v);
},
When you specify that the control uses a four year date "yyyy", it will only do the return d.setUTCFullYear(v);, which will get you the previous century that JavaScript gives you. When you specify that it use the two year date "yy", it will do the correct 2000+ that you need for the current century.
So if you want the correct two year date to be 2016, 2017, etc., you need to set your datepicker to use the "yy" like so:
$('#tbPurchaseDate').datepicker({
format: 'mm/dd/yy',
autoclose: true,
todayBtn: 'linked',
todayHighlight: true,
orientation: 'bottom auto'
});
Or you can change the "yyyy" setting in the bootstrap-datepicker.js to match the "yy" version, but then you'd have to remember to do that every time you update the datepicker js file via nuget. It's much easier to just change your format setting.
Of course, if you want the full 4 digit year to display in the control, then you might want to try one of the elaborate fixes listed here or just set the "yyyy" to what the "yy" is in the js file.
Or just update your code to the latest version (1.6.4 right now) and "yyyy" and "yy" are the same and you use assumeNearbyYear: true as noted in another answer here.
For me, the best solution was to customize parseDate function in bootstrap-datepicker.js file directly. Inside a function, there is variable setters_map with yyyy property which I modified a bit. Here is my solution:
yyyy: function(d,v) {
if (v.toString().length == 2 && v <= 30) {
v = 2000 + parseInt(v);
}
return d.setUTCFullYear(v);
},
In my case it was needed to convert only years that are less or equals 30.
In the update function of bootstrap-datepicker.js I added this block of code:
var str = this.element.prop('value');
var defaulted = false;
if (str.lastIndexOf("/") >= 0 && (str.match(/\//g) || []).length == 2)
{
var yr = str.substring(str.lastIndexOf("/") + 1);
if (yr.length <= 2)
defaulted = true;
}
if (this.date.getFullYear() < 2000 && defaulted) {
this.date.setFullYear(this.date.getFullYear() + 100);
}
right before the viewdate is set on this line:
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
It will work 100% if you update below two line in UTCDate() of bootstrap-datepicker.js core file:
function UTCDate(){
/* Date defaulted date from 2000 if entered date year less than 4 degit*/
if(arguments!=null && arguments[0].toString().length<4)
arguments[0] = 2000 + arguments[0];
return new Date(Date.UTC.apply(Date, arguments));
}
What I am trying to do here is this - I want to give index to only the workdays in each week.
So, if in a week, Monday and Wednesday are holidays, then Tuesday should get 1, Thursday should get 2, Friday should get the index 3. Otherwise, in a normal week without any holidays, Monday should get 1, Tuesday 2, Wednesday 3, and so on ...
Here is the code I have written (I haven't coded in years now, so please pardon the crude approach)
Sheet 'Holidays' contains a list of holidays in the column B starting from row 2
Variable date is the date for which I want to find out the index for
Variable dayOfTheWeek is the number of day of 'date' counted from last Sunday, so if date is a Monday, dayOfTheWeek is 1; if date is Tuesday, dayOfTheWeek is 2, and so on ...
function indexOfWorkdayOfTheWeek (date, dayOfTheWeek, lastSundayDate)
{
var activeSheet = SpreadsheetApp.getActiveSpreadsheet();
var activeCell = activeSheet.getActiveRange();
var activeRow = activeCell.getRowIndex();
var activeColumn = activeCell.getColumn();
var count = 1;
for (var j = 1; j < dayOfTheWeek; j++)
{
var date2 = lastSundayDate.valueOf() + j*86400;
Logger.log('Date ' + j + ' is:' + date2);
Logger.log('Last Sunday is:' + lastSundayDate);
if (holidayOrNot(date2) == true)
{
}
else
{
count = count + 1;
}
}
return count;
}
function holidayOrNot(date2)
{
var holidaysSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Holidays');
var listOfHolidays = holidaysSheet.getSheetValues(2, 2, 95, 1);
var isDateMatch = false;
for (var k = 0; k < 90; k++)
{
if (date2 == listOfHolidays[k].valueOf())
{
isDateMatch = true;
break;
}
else
{
continue;
}
}
return isDateMatch;
}
I think the problem is two-fold here:
The date2 calculation isn't working for some reason (var date2 = lastSundayDate.valueOf() + j*86400;)
The function holidayOrNot is returning false, no matter what, even if it encounters a holiday ... the condition date2 == listOfHolidays[k] isn't working for some reason...
Help would be appreciated!
maybe this method below could help you in your calculations, it returns an integer corresponding to the day of the year so if you apply this to your holidays days and compare to the days of interest it could be a good way to find matches.
here it is, just add these lines outside of any function in your script (so you can use it anywhere) then use it like this :
var d = new Date().getDOY();
Logger.log(d)
Here the method :
Date.prototype.getDOY = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((this - onejan) / 86400000);
}
Assuming that lastSundayDate is being passed around correctly, I see a glaring problem:
lastSundayDate.valueOf().
valueOf() on Date objects returns the primitive value... it looks like you're going for adding a day to the date (86400 seconds * j)? I can't tell what the logic is supposed to be here. But the valueOf() date2 is definitely giving you an integer something like: 1384628769399 (see here).
What you really want to accomplish is something like Date.getDay(), or something similar so that you can add hours, days, etc. to the original Date. This is likely the source of all your problems.
What you can do is read the Mozilla Developer Network documentation on Date objects to see all of the functions on Dates and their uses. You can greatly simplify what you're trying to do by using these functions, instead of doing abstract operations like j * 86400.
It should also be noted that you can do simple operations such as the following, to add 4 hours to the current Date (time):
var myDate = new Date();
Logger.log(myDate); // ~ console.write
var laterDate = new Date(myDate.setHours(myDate.getHours() + 4));
Logger.log(laterDate); // ~ console.write
which gives the following:
[13-11-16 14:13:38:947 EST] Sat Nov 16 14:13:38 GMT-05:00 2013
[13-11-16 14:13:38:954 EST] Sat Nov 16 18:13:38 GMT-05:00 2013
Working with dates can be tricky - but it's always best to use the simplest methods that are available, which are built into the Date objects themselves. There are also numerous other libraries that provide extended functionality for Dates such as Date js.
If you're still running into your problem after attempting to try using methods I displayed above, please run your script and post both the Execution Transcript and the content of the Logger so that I can help you narrow down the issue :)
I been working on parsing out bookmarks from an export file generated by google bookmarks. This file contains the following date attributes:
ADD_DATE="1231721701079000"
ADD_DATE="1227217588219000"
These are not standard unix style timestamps. Can someone point me in the right direction here? I'll be parsing them using c# if you are feeling like really helping me out.
Chrome uses a modified form of the Windows Time format (“Windows epoch”) for its timestamps, both in the Bookmarks file and the history files. The Windows Time format is the number of 100ns-es since January 1, 1601. The Chrome format is the number of microseconds since the same date, and thus 1/10 as large.
To convert a Chrome timestamp to and from the Unix epoch, you must convert to seconds and compensate for the difference between the two base date-times (11644473600).
Here’s the conversion formulas for Unix, JavaScript (Unix in milliseconds), Windows, and Chrome timestamps (you can rearrange the +/× and -/÷, but you’ll lose a little precision):
u : Unix timestamp eg: 1378615325
j : JavaScript timestamp eg: 1378615325177
c : Chrome timestamp eg: 13902597987770000
w : Windows timestamp eg: 139025979877700000
u = (j / 1000)
u = (c - 116444736000000) / 10000000
u = (w - 1164447360000000) / 100000000
j = (u * 1000)
j = (c - 116444736000000) / 10000
j = (w - 1164447360000000) / 100000
c = (u * 10000000) + 116444736000000
c = (j * 10000) + 116444736000000
c = (w / 10)
w = (u * 100000000) + 1164447360000000
w = (j * 100000) + 1164447360000000
w = (c * 10)
Note that these are pretty big numbers, so you’ll need to use 64-bit numbers or else handle them as strings like with PHP’s BC-math module.
In Javascript the code will look like this
function chromeDtToDate(st_dt) {
var microseconds = parseInt(st_dt, 10);
var millis = microseconds / 1000;
var past = new Date(1601, 0, 1).getTime();
return new Date(past + millis);
}
1231721701079000 looks suspiciously like time since Jan 1st, 1970 in microseconds.
perl -wle 'print scalar gmtime(1231721701079000/1_000_000)'
Mon Jan 12 00:55:01 2009
I'd make some bookmarks at known times and try it out to confirm.
Eureka! I remembered having read the ADD_DATE’s meaning at some website, but until today, I could not find it again.
http://MSDN.Microsoft.com/en-us/library/aa753582(v=vs.85).aspx
offers this explanation as a “Note” just before the heading “Exports and Imports”:
“Throughout this file[-]format definition, {date} is a decimal integer that represents the number of seconds elapsed since midnight January 1, 1970.”
Before that, examples of {date} were shown:
<DT><H3 FOLDED ADD_DATE="{date}">{title}</H3>
…
and
<DT>{title}
…
Someday, I will write a VBA macro to convert these to recognizable dates, but not today!
If someone else writes a conversion script first, please share it. Thanks.
As of the newest Chrome Version 73.0.3683.86 (Official Build) (64-bit):
When I export bookmark, I got an html file like "bookmarks_3_22_19.html".
And each item has an 'add_date' field which contains date string. like this:
Stack Overflow
This timestamp is actually seconds (not microseconds) since Jan 1st, 1970. So we can parse it with Javascript like following code:
function ChromeTimeToDate(timestamp) {
var seconds = parseInt(timestamp, 10);
var dt = new Date();
dt.setTime(seconds * 1000);
return dt;
}
For the upper example link, we can call ChromeTimeToDate('1553220774') to get Date.
ChromeTimeToDate('1553220774')
12:09:03.263 Fri Mar 22 2019 10:12:54 GMT+0800 (Australian Western Standard Time)
Initially looking at it, it almost looks like if you chopped off the last 6 digits you'd get a reasonable Unix Date using the online converter
1231721701 = Mon, 12 Jan 2009 00:55:01 GMT
1227217588 = Thu, 20 Nov 2008 21:46:28 GMT
The extra 6 digits could be formatting related or some kind of extended attributes.
There is some sample code for the conversion of Unix Timestamps if that is in fact what it is.
look here for code samples: http://www.epochconverter.com/#code
// my groovy (java) code finally came out as:
def convertDate(def epoch)
{
long dv = epoch / 1000; // divide by 1,000 to avoid milliseconds
String dt = new java.text.SimpleDateFormat("dd/MMM/yyyy HH:mm:ss").format(new java.util.Date (dv));
// to get epoch date:
//long epoch = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 01:00:00").getTime() * 1000;
return dt;
} // end of def
So firefox bookmark date exported as json gave me:
json.lastModified :1366313580447014
convert from epoch date:18/Apr/2013 21:33:00
from :
println "convert from epoch date:"+convertDate(json.lastModified)
function ConvertToDateTime(srcChromeBookmarkDate) {
//Hp --> The base date which google chrome considers while adding bookmarks
var baseDate = new Date(1601, 0, 1);
//Hp --> Total number of seconds in a day.
var totalSecondsPerDay = 86400;
//Hp --> Read total number of days and seconds from source chrome bookmark date.
var quotient = Math.floor(srcChromeBookmarkDate / 1000000);
var totalNoOfDays = Math.floor(quotient / totalSecondsPerDay);
var totalNoOfSeconds = quotient % totalSecondsPerDay;
//Hp --> Add total number of days to base google chrome date.
var targetDate = new Date(baseDate.setDate(baseDate.getDate() + totalNoOfDays));
//Hp --> Add total number of seconds to target date.
return new Date(targetDate.setSeconds(targetDate.getSeconds() + totalNoOfSeconds));
}
var myDate = ConvertToDateTime(13236951113528894);
var alert(myDate);
//Thu Jun 18 2020 10:51:53 GMT+0100 (Irish Standard Time)
#Python program
import time
d = 1630352263 #for example put here, if (ADD_DATE="1630352263")
print(time.ctime(d)) #Mon Aug 30 22:37:43 2021 - you will see