Timezone Manipulation - laravel

I'm working on a project (online game) where users have the ability to use a coded 'airport' to travel to different countries & cities. Once they have travelled, the cityid within the database will update for example:
cityid = 1 (England - London)
cityid = 2 (USA - LA)
Therefore if a user travels from England to the USA it will store database side cityid = 2.
Now,
Whilst this is functional, I wish to incorporate timezone changes into it (if at all possible) I have tried:
if ($user->cityid == 3)
{
$timestamp ='1502448414'; //Timestamp which you need to convert
$dt = new \DateTime("#$timestamp");
$destinationTimezone = new \DateTimeZone('Mexico/General'); // To which timezone you need to convert
$dt->setTimeZone($destinationTimezone); // Set timezone
echo 'Mexico: '. $dt->format('H:i a'), "\n"; // Echo your changed datetime
}
As you can see, I have used Mexico as a demo to try and figure out my approach.
However, this only fetches the timestamped time rather than the realtime. Im aware, I could simply add the timestamp into a database table and then run a cron every second to update the table but this seems rather a long winded route.
Now within app.php the standard setting is UTC which runs as a realtime clock by returning: date('H:i:s').
My question is (after a lot of google searching) is there a way to manipulate this to make date() output the new time of (USA) when it has been travelled to?
Apologies that I cannot add anymore coding into this question, I have no real idea of how to approach it other than the one stated above.

Using Carbon
if ($user->cityid == 3) {
$dt = \Carbon\Carbon::now("Your current location timezone");
$dt->setTimeZone('Mexico/General');
echo 'Mexico: '. $dt->format('H:i a'), "\n";
}

Related

Script to create same Google Classroom assignment for each day of the school year

Does anyone know of a script that I could adapt to create the same assignment for each school day of a given school year? For example, I would like to create the assignment "Practice your Anki deck. Submit screenshot of your stats" every school day in our class BasicSkills. Ideally, the assignment would be scheduled the week before it was due. This would be a great time saver for those of us elementary school teachers using Google Classroom who have lots of daily and weekly repeating tasks.
I was a programmer many years ago and could adapt an existing script but would struggle to get this working just based on the API description. Thanks.
I think you can, it just depends on how you'll approach it. I'll give you a skeletal structure of the code:
function myFunction() {
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
var i;
for (i = 0; i < 3; i++){
var dat = new Date();
Logger.log(dat.addDays(i))
var ClassSource = {
title: "Test File" + dat.addDays(i),
state: "DRAFT",
workType: "ASSIGNMENT"
};
Classroom.Courses.CourseWork.create(ClassSource, 4965804775)
}
//Logger.log(exec);
}
How to approach your goal:
Ideally you want to create the assignment in one go but I don't recommend since there are limitations that you'll encounter (e.g. timeout).
Next, if ever you'll decide to do it in one go, I recommend you to use Utilities.sleep(1000) between calls.
You can also create a list of dates that don't have a class like saturday, sunday, holiday.
Sample result:
Hope this helps.

nested for loops in stata

I am having trouble to understand why a for loop construction does not work. I am not really used to for loops so I apologize if I am missing something basic. Anyhow, I appreciate any piece of advice you might have.
I am using a party level dataset from the parlgov project. I am trying to create a variable which captures how many times a party has been in government before the current observation. Time is important, the counter should be zero if a party has not been in government before, even if after the observation period it entered government multiple times. Parties are nested in countries and in cabinet dates.
The code is as follows:
use "http://eborbath.github.io/stackoverflow/loop.dta", clear //to get the data
if this does not work, I also uploaded in a csv format, try:
import delimited "http://eborbath.github.io/stackoverflow/loop.csv", bindquote(strict) encoding(UTF-8) clear
The loop should go through each country-specific cabinet date, identify the previous observation and check if the party has already been in government. This is how far I have got:
gen date2=cab_date
gen gov_counter=0
levelsof country, local(countries) // to get to the unique values in countries
foreach c of local countries{
preserve // I think I need this to "re-map" the unique cabinet dates in each country
keep if country==`c'
levelsof cab_date, local(dates) // to get to the unique cabinet dates in individual countries
restore
foreach i of local dates {
egen min_date=min(date2) // this is to identify the previous cabinet date
sort country party_id date2
bysort country party_id: replace gov_counter=gov_counter+1 if date2==min_date & cabinet_party[_n-1]==1 // this should be the counter
bysort country: replace date2=. if date2==min_date // this is to drop the observation which was counted
drop min_date //before I restart the nested loop, so that it again gets to the minimum value in `dates'
}
}
The code works without an error, but it does not do the job. Evidently there's a mistake somewhere, I am just not sure where.
BTW, it's a specific application of a problem I super often encounter: how do you count frequencies of distinct values in a multilevel data structure? This is slightly more specific, to the extent that "time matters", and it should not just sum all encounters. Let me know if you have an easier solution for this.
Thanks!
The problem with your loop is that it does not keep the replaced gov_counter after the loop. However, there is a much easier solution I'd recommend:
sort country party_id cab_date
by country party_id: gen gov_counter=sum(cabinet_party[_n-1])
This sorts the data into groups and then creates a sum by group, always up to (but not including) the current observation.
I would start here. I have stripped the comments so that we can look at the code. I have made some tiny cosmetic alterations.
foreach i of local dates {
egen min_date = min(date2)
sort country party_id date2
bysort country party_id: replace gov_counter=gov_counter+1 ///
if date2 == min_date & cabinet_party[_n-1] == 1
bysort country: replace date2 = . if date2 == min_date
drop min_date
}
This loop includes no reference to the loop index i defined in the foreach statement. So, the code is the same and completely unaffected by the loop index. The variable min_date is just a constant for the dataset and the same each time around the loop. What does depend on how many times the loop is executed is how many times the counter is incremented.
The fallacy here appears to be a false analogy with constructs in other software, in which a loop automatically spawns separate calculations for different values of a loop index.
It's not illegal for loop contents never to refer to the loop index, as is easy to see
forval j = 1/3 {
di "Hurray"
}
produces
Hurray
Hurray
Hurray
But if you want different calculations for different values of the loop index, that has to be explicit.

What is the difference between TYPE_STEP_COUNT_DELTA and AGGREGATE_STEP_COUNT_DELTA data type in Google Fit Android Api?

The Google Fit API describes two of these data types of the Sensor API. However both seem to be returning the same data. Can anyone explain the difference?
TYPE_STEP_COUNT_DELTA:
In the com.google.step_count.delta data type, each data point represents the number of steps taken since the last reading.
AGGREGATE_STEP_COUNT_DELTA:
Aggregate number of steps during a time interval.
You can see more here:
https://developers.google.com/android/reference/com/google/android/gms/fitness/data/DataType
// Setting a start and end date using a range of 1 week before this moment.
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.WEEK_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();
java.text.DateFormat dateFormat = getDateInstance();
Log.i(TAG, "Range Start: " + dateFormat.format(startTime));
Log.i(TAG, "Range End: " + dateFormat.format(endTime));
DataReadRequest readRequest = new DataReadRequest.Builder()
// The data request can specify multiple data types to return, effectively
// combining multiple data queries into one call.
// In this example, it's very unlikely that the request is for several hundred
// datapoints each consisting of a few steps and a timestamp. The more likely
// scenario is wanting to see how many steps were walked per day, for 7 days.
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
// Analogous to a "Group By" in SQL, defines how data should be aggregated.
// bucketByTime allows for a time span, whereas bucketBySession would allow
// bucketing by "sessions", which would need to be defined in code.
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();

Why date validation in Google sheets rejects today's date before 8:00am?

I've created a Google sheet to keep a list of work tasks with a column to track the date on which items are created, and built a script to automatically populate the cells in that column with the day's date when a new line is inserted.
The cell (e.g. G9) that is target of the script uses the following validation formula to make sure that when users change the date, they use a date that is neither a weekend nor in the future:
=and(isdate(G9), weekday(G9,2)<6, G9<=today())
IT ONLY WORKS BUT ONLY IF THE SCRIPT IS RUN ANYTIME AFTER 8:00am ! If I try using it any earlier the cell validation will reject the input!
The script looks like this (curRow is the number of the row that's been added):
// Adds today's date without using =today()
var myrangename = "G"+curRow;
var dateCell = sheet.getRange(myrangename);
var d = new Date();
var dateArr = [];
dateArr[0]=d.getFullYear();
dateArr[1]=d.getMonth() + 1; //Months are zero based
dateArr[2]=d.getDate();
dateCell.setValue(dateArr.join('/'));
(n.b.: I cannot use the script to simply put =today() in the cell because all the entries would change every day. )
WHY DOES IT ONLY WORK AFTER 8:00AM? Is Google somehow running on a different time zone than my computer?? I'm based in the UK, so using BST, but that shouldn't be a problem, shouldn't it...?
Try
var d = new Date();
var d = Utilities.formatDate(d, "GMT+1", "yyyy-MM-dd HH:mm:ss");
I am not sure if google would recognise BST as a time zone, but you could also try
var d = Utilities.formatDate(d, "BST", "yyyy-MM-dd HH:mm:ss");
Thank you for your suggestion, Aprillion. Turns out that a Google Sheets file has its own internal time-zone setting! which in my case was set to American Pacific time (so 8hrs behind)
(You'd think it would pick up the date and time info automatically from Windows, like other applications do!)
To set the sheet's time-zone to the correct one, you need to go to the main menu, click 'File', then 'Spreadsheet settings...', and adjust as necessary.
The script and validation now all work fine.
Thank you all for your help.

Get the the most recent and the one before the most recent item

I have a table with many anniversaries : Date + Name.
I want to display the next anniversary and the one after with Linq.
How can i build the query ?
I use EF
Thanks
John
Just order by date and then use the .Take(n) functionality
Example with a list of some objects assuming you want to order by Date then Name:
List<Anniversaries> annivDates = GetAnnivDates();
List<Anniversaries> recentAnniv = annivDates.OrderBy(d => d.Date).ThenBy(d => d.Name).Take(2).ToList();
If the anniversaries are stored in regular DateTime structs, they may have the 'wrong' year set (i.e. wedding or birth year). I suggest writing a function which calculates the next date for an anniversary (based on the current day) like:
static DateTime CalcNext(DateTime anniversary) {
DateTime newDate = new DateTime(DateTime.Now.Year, anniversary.Month, anniversary.Day);
if (newDate < DateTime.Now.Date)
newDate = newDate.AddYear(1);
return newDate;
}
Then you proceed with sorting the dates and taking the first two values like described in the other postings:
(from e in anniversaries orderby CalcNext(e.Date) select e).Take(2)

Resources