How to get the every week by google spread sheet - google-apps-script

I want to have date of every weeks.
I put 07/02/2022 in F5 cell and put =EDATE(F5 + 7) in G5 cell
But N/A comes in G5
I guess maybe I put 07/02/2022 in F5 in a wrong way..
What should I do?

read the error message:
Wrong number of arguments to EDATE. Expected 2 arguments, but got 1 arguments.
correct G5 to =EDATE(F5,7)
In case you refer to tomorrow's date, that is 2/7/2022.
You are, if you read the help, adding 7 months with the command above.

The date of the next week starting on any day
function nextWeekDateStartingOnThis(day = 1) {//Sun(0) - Sat(6)
let dt = new Date();
let nd = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate() + 7 - dt.getDay() + day);
Logger.log(nd);
return nd;//this returns the date of the next monday because day = 1
}
If you want the date of the next tuesday then make day = 2

Related

Is there a convienient way to call a function multiple times without a loop?

I am currently making some code to randomly generate a set of random dates and assigning them to a matrix. I wish to randomly generate N amount of dates (days and months) and display them in a Nx2 matrix. My code is as follows
function dates = dategen(N)
month = randi(12);
if ismember(month,[1 3 5 7 8 10 12])
day = randi(31);
dates = [day, month];
elseif ismember(month,[4 6 9 11])
day = randi(30);
dates = [day, month];
else
day = randi(28);
dates = [day, month];
end
end
For example if I called on the function, as
output = dategen(3)
I would expect 3 dates in a 2x3 matrix. However, I am unsure how to do this. I believe I need to include N into the function somewhere but I'm not sure where or how.
Any help is greatly appreciated.
You can do it using logical indexing as follows:
function dates = dategen(N)
months = randi(12, 1, N);
days = NaN(size(months)); % preallocate
ind = ismember(months, [1 3 5 7 8 10 12]);
days(ind) = randi(31, 1, sum(ind));
ind = ismember(months, [4 6 9 11]);
days(ind) = randi(30, 1, sum(ind));
ind = ismember(months, 2);
days(ind) = randi(28, 1, sum(ind));
dates = [months; days];
end

Calculate time based on business working hours

Add numbers of hours to a timestamp and make sure that the output is within working hours.
For example:
Open Time -> 9:00 AM
Close Time -> 6:00 PM
First Date -> 12/1/2020 12:00 PM
Add Time -> 7 hours
Result -> 13/1/2020 10:00 AM
I am trying to achieve this using GAS ES5/ES6
Already tried a formula which is very close to this logic:
Cell A7 = First Date
Cell G5 = Add Time
Cell B1 = 9/24-18/24
Sheet2!A:A = List of Holidays to Skip
0000011 = Skips Saturday and Sunday
=if(A7,if(and(hour(A7+G$5)>9,(hour(A7+G$5)<18)),A7+G$5,workday.intl(int(A7+G$5+$B$1),1,"0000011",Sheet2!A:A)+hour(A7+G$5+$B$1)/24),"")
I think you are looking for this:
function myFunction() {
var open_h = 9 // 24h
var close_h = 18 //24h
var add_h = 7 // number of hours
var d = new Date();
d.setDate(d.getDate() + (1 + 7 - d.getDay()) % 7);
next_Monday = d.getDate()
var first_date = new Date() ;
var end_date = new Date();
end_date.setTime(end_date.getTime() + (add_h*60*60*1000))
if (end_date.getDate()>first_date.getDate()){
end_date.setDate((new Date()).getDate());
end_date.setHours(23, 0 , 0);
}
if (end_date.getHours()>=close_h){
if (end_date.getDay() == 5 || end_date.getDay() == 6 || end_date.getDay() == 0 ) {end_date.setDate(next_Monday) }
else {end_date.setDate(end_date.getDate() + 1)} // tomorrow
var end_time = end_date.getHours()-close_h + open_h
end_date.setHours(end_time, 0, 0);
}
Logger.log(end_date)
} // end function
end_date will give you the desired result.
Edit: it also takes weekends into consideration.

Octave Calculus with matrix

i'm developing a program in octave that i will explain as i put the code.
So i have this matrix in a file called matprec.m:
function [res1] = obtemDadosPrec()
res1 = [
1,2001,1,2,0.00;
1,2001,1,5,5.33;
2,2001,1,5,4.57;
3,2001,1,5,5.33;
4,2001,1,5,5.59;
5,2001,1,5,4.32;
2,2001,1,13,0.00;
3,2001,1,13,0.00;
4,2001,1,13,0.00;
3,2001,1,30,30.73;
2,2001,2,1,1.02;
3,2001,2,1,1.52;
4,2001,2,1,1.78;
5,2001,2,1,1.27;
1,2001,2,2,1.78;
2,2001,2,2,1.27;
3,2001,2,2,1.78;
4,2001,2,2,2.03;
5,2001,2,2,1.78;
1,2001,3,4,18.03;
3,2001,3,4,15.75;
5,2001,3,4,17.53;
1,2001,3,5,13.46;
2,2001,3,5,12.19;
3,2001,3,5,11.94;
4,2001,3,5,9.65;
5,2001,3,5,10.92;
2,2001,4,30,0.00;
4,2001,4,30,0.00];
format short g
return
endfunction
so in this matrix the first column is just the station where we measure the amount of precipitation, the second is the year, the third is the month, the fourth is the day and the fifth is the value of precipitation.
And what i want to do in another file is call this matrix and do the following calculus, in the month 1 i want do the average on all the days for example:
in month 1 day 5 i have 5 values 5.33, 4.57, 5.33, 5.59, 4.32, so i would do
(5.33 + 4.57 + 5.33 + 5.59 + 4.32)/5 = 5.028
And i want to do that for all the days and when i have all the days i would add them all to know the amount of precipitation in that month, and do that for all the 4 months.
I'm kind of stuck there if you could help me i would appreciate, thanks a lot!
First, get your array
>> Result = obtemDadosPrec();
Then get a logical array where rows corresponding to month == 1 are true (i.e. 1) and all others are false (i.e. 0)
>> month1Indices = Result(:,3) == 1;
Use this logical array to perform logical indexing and isolate only the 'true' rows.
>> month1Rows = Result(month1Indices, :);
Repeat same procedure to isolate 'day 5'
>> day5Indices = month1Rows(:,4) == 5;
>> day5Rows = month1Rows(day5Indices , :);
Calculate the average of the 5th column.
>> mean(day5Rows(:,5))
ans = 5.028

SSRS Expression First Day of of First Week of Current Year

Everyone,
I have a question that has stumped me for a day and can't figure out. What I am looking for is a formula in SSRS Expression that will tell me what the date is for the first day of the first ISO week of the current year.
For Example:
2014 would yield: 12/30/2013. The reason for this would be that the first ISO week of the 2014 year is from (12/30/2013) - (01/05/2014).
2013 would yield: 12/31/2012
I would appreciate any help anyone?
Thanks,
You can use this function:
Public Function dtFirstDayOfISOYear(ByVal intYear As Integer) as Datetime
'the first week of a ISO year is the week that contains the first Thursday of the year (and, hence, 4 January)
Dim intDayOfWeek As Integer = CInt(New DateTime(intYear, 1, 4).DayOfWeek)
'ISO weeks start with Monday
If intDayOfWeek < DayOfWeek.Monday Then intDayOfWeek = intDayOfWeek + 7
Return DateAdd(DateInterval.Day, -intDayOfWeek + 1, New DateTime(intYear, 1, 4))
End Function
And call it using an Expression like this:
=Code.dtFirstDayOfISOYear(2014)
You can also use a standalone Expression like this:
=DateAdd("d", (-1) * (CInt(New DateTime(2014, 1, 4).DayOfWeek) + IIf(CInt(New DateTime(2014, 1, 4).DayOfWeek) < DayOfWeek.Monday, 7, 0)) + 1, New DateTime(2014, 1, 4))

Determining time ranges within pre-defined shifts in MySQL

I'm working with a timecard database and trying to determine how much time for each punch falls into each one of three distinct shift periods.
For example
shift 1 = 7AM - 3pm
shift 2 = 3pm - 11pm
shift 3 = 11pm - 7am
Joe clocks in at 6:45AM and out at 1:45PM
15 minutes of this would need to be calculated as time on shift 3, but I'm not sure how to go about slicing out that bit of time in MySQL. All I have are a time in and time out field.
There are three shift periods:
Shift TimeStart TimeEnd
1 07:00 15:00
2 15:00 23:00
3 23:00 07:00
Sample Data
ID TimeIn TimeOut Hours
100 2014-07-31 06:45 2014-07-31 13:45 7
Desired Result
ID Shift TimeWorked
100 1 06:45
100 2 00:00
100 3 00:15
SQL Fiddle
I was able to come up with a solution for this using PHP.
What I did was loop through each punch, minute by minute, and determine what shift each one minute time span applies to. Within the loop, I increment one of 4 variable for shifts 1, 2, 3 or 0(no shift pay), and at the end, dump those variables to the database for the record being analyzed.
$query = "SELECT * FROM source_filtered_timecard";
$result_set = mysqli_query($connection, $query);
while($record = mysqli_fetch_assoc($result_set)) {
$checkCount++;
$shift1_hours = 0; $shift2_hours = 0;
$shift3_hours = 0; $shift0_hours = 0;
$time = strtotime($record['in_time']);
$time_out = strtotime('-1 Minute',strtotime($record['out_time']));
while($time <= $time_out) {
$mysql_time = date('G:i:s',$time);
//SELECT SHIFT CODE THAT APPLIES TO CURRENT PIT//
$query = "SELECT shift FROM shift_rules WHERE STR_TO_DATE('{$mysql_time}','%H:%i:%S') BETWEEN start_time_24 AND end_time_24 LIMIT 1";
$current_shift_set = mysqli_query($connection, $query);
if(mysqli_num_rows($current_shift_set) == 1) {
$current_shift = mysqli_fetch_assoc($current_shift_set);
if($current_shift['shift'] == '1'){$shift1_hours++;}
elseif($current_shift['shift'] == '2'){$shift2_hours++;}
elseif($current_shift['shift'] == '3'){$shift3_hours++;}
else{$shift0_hours++;}
} else {
$shift0_hours++;
}
//INCRIMENT TIME BY 1 MINUTE//
$time = strtotime("+1 minute",$time);
}
$shift1_hours = $shift1_hours/60;
$shift2_hours = $shift2_hours/60;
$shift3_hours = $shift3_hours/60;
$shift0_hours = $shift0_hours/60;
//UPDATE TIMECARD ROWS WITH SHIFT HOURS//
$query = "UPDATE source_filtered_timecard
SET shift1_time = {$shift1_hours},
shift2_time = {$shift2_hours},
shift3_time = {$shift3_hours},
shift0_time = {$shift0_hours}
WHERE id = '{$record['id']}'";
$update = mysqli_query($connection, $query);
}
I'd do this in PHP. Looking at Joe's example, it is initially tempting to try to work out how his data maps onto the shift rules. However, I think it would be a neater solution to do it the other way around i.e. map the rules onto his data, until there is no data to classify.
The algorithm might go a bit like this:
Joe's remaining time is 6:45 - 13:45
Let's map the first rule onto it (i.e. how much of this rule contributes to that range?):
shift 1 = 7:00 - 15:00 (6:45 hours)
Now Joe's remaining time is:
6:45 - 7:00
Do the next rule:
shift 2 = 15:00 - 23:00 (0 hours)
Joe's remaining time is therefore unchanged. And finally the last rule:
shift 3 = 23:00 - 1d7:00 (0:15 hours)
There are a few things to note:
The amount of worked time could be stored in an array (a "worked time set"). It starts off as a simple start and end, but if a rule removes a chunk of time from the middle, it may split into two starts and two ends
When applying a rule, convert them to actual timestamps (i.e. a date and a time) so the wrapping to the next day works correctly
Write a function that takes a worked time set, plus a rule start and end timestamp, modifies a worked time set, and returns a number of hours for the rule
First you need to add day column for differentiate time from 23:59:59 to next day time.
id| shift_name | time_start | time_end | day
1 | Day Shift | '07:00:00' | '18:59:59' | 1
2 | Night Shift | '19:00:00' | '06:59:59' | 2
Procedure :
DELIMITER $$ CREATE PROCEDURE sp_check_shift(IN intime time) PROC: begin IF(intime>='00:00:01' AND intime<='23:59:59') THEN IF ( SELECT 1 FROM tbl_shift WHERE time_start<=intime AND time_end>=intime AND day=1) THEN SELECT shift_name FROM tbl_shift WHERE time_start<=intime AND time_end>=intime AND day=1;ELSEIF ( SELECT 1 FROM tbl_shift WHERE time_start<=intime AND day=2) THEN SELECT shift_name FROM tbl_shift WHERE time_start<=intime AND day=2;ELSEIF ( SELECT 1 FROM tbl_shift WHERE time_end>=intime AND day=2) THEN SELECT shift_name FROM tbl_shift WHERE time_end>=intime AND day=2;END IF;ELSE SELECT 'Invalid Time' shift_name;END IF;END$$ delimiter ;