Synchronizing time in application via JavaScript on iPad - c#

Scenario:
I have a iPad web app which connects to my Exchange server to display the visibility of meeting rooms in Outlook.
The clock must be very accurate (within 5 seconds of the Exchange Server time)
My problem is:
The iPad syncs its time with apples timeserver and there is no way of changing this without jailbreaking the iPad
The iPad clock is not in sync with our server
My current solution:
I have a Clock.aspx page which returns the current time and displays it in the correct div:
var getTime = function () {
$.get('Clock.aspx', function (data) {
$('#txt').html('<h1>' + data + '</h1>');
});
}
However:
This is very inefficient as the call to the server is every 10 seconds (this causes the iPad to crash once every 3/4 days)
What I would like to do:
Is pull the time from Clock.aspx once a hour and increment it using javascript for the rest of the time which will reduce the calls to the server significantly.
Please advise me on the best and most efficient way to do this.
If you have any other suggestions on ways to improve the efficiency I would also love to hear them.

Okay, this isn't perfect but meets my requirements for now - I'd once again appreciate it if more efficient and accurate solutions come up!
var hour = parseInt("<%=DateTime.Now.Hour %>", 10);
var minute = parseInt("<%=DateTime.Now.Minute %>", 10);
var second = parseInt("<%=DateTime.Now.Second %>", 10);
// var x = hour.tostring() +":"+ minute.tostring() +":"+ second.tostring();
// alert(x);
function showTime() {
second++;
if (second > 59) {
second = 0;
minute++;
}
if (minute > 59) {
minute = 0;
hour++;
}
minute = checkTime(minute);
second = checkTime(second);
var clock = hour.toString() + ":" + minute.toString() + ":" + second.toString();
document.getElementById("txt").innerHTML = "<h1>" + clock + "</h1>";
function checkTime(i) {
return (i < 10 ? '0' : '') + i;
}
}
setInterval('showTime()', 1000);

Having used my original answer for a few days I noticed that the sync was out, this script sync's with the server time every hour to re-sync the time accordingly, this means that the accuracy of the clock is very very close with the server. The previous script could lose upto 5 minutes per day. I hope this helps someone!
var serverDate;
function getServerDate() {
serverDate = new Date("<%=DateTime.Now %>");
}
function tick() {
serverDate.setSeconds(serverDate.getSeconds() + 1);
var min = serverDate.getMinutes();
var hour = serverDate.getHours();
var sec = serverDate.getSeconds();
if (min == 30) {
$.get('Clock.aspx?type=2', function (data) {
serverDate = new Date(data.split(">")[1].split("<")[0]);
min = serverDate.getMinutes();
hour = serverDate.getHours();
sec = serverDate.getSeconds();
});
}
if (hour < 10) hour = "0" + hour;
if (min < 10) min = "0" + min;
if (sec < 10) sec = "0" + sec;
document.getElementById("txt").innerHTML = "<h1>" + hour + ":" + min + ":" + sec; + "</h1>";
}
window.onload = function () {
getServerDate();
setInterval("tick()", 1000);
}
Edited to add that clock.aspx is a page which outputs DateTime.Now.ToString()

Related

How to setup 28 unique local notifications (1 each day) that repeat after 28 days at 9 AM

I am looking to setup a batch of 28 local notifications (1 each day) that will repeat again after 28 days until cancelled. These have to be set to be triggered at 9:00 AM everyday.
I have tried to set these notifications using the UNCalendarNotificationTrigger by giving datecomponents and adding a day by looping thru all the 28 and set repeating as true.
The downside is UNCalendarNotificationTrigger sets for the calendar month and not 28 days, so for day 29, 30 & 31 there are no notifications displayed. I need something that will trigger back to back.
This question has provided with some idea of how to use UNTimeIntervalNotificationTrigger, this works for one set of recurring notifications, but after that, they trigger at different intervals.
To make things easier to test, I have changed the frequency to 1 message every minute for 5 messages and then schedule 5 recurring messages using intervals. These recurring messages have repeat:true. After the 5 recurring messages, they don't follow the same pattern.
for (int i = 0; i < 5; i++)
{
NSDateComponents DateComponents = new NSDateComponents();
DateComponents.Minute = DateToSet.AddMinutes(i).Minute;
DateComponents.Second = 0;
UNMutableNotificationContent content = new UNMutableNotificationContent { Title = "Title " + i, Body = "Body " + i, Sound = UNNotificationSound.Default, CategoryIdentifier = "MyCategoryId" };
UNCalendarNotificationTrigger trigger =
UNCalendarNotificationTrigger.CreateTrigger(DateComponents, false);
UNNotificationRequest request =
UNNotificationRequest.FromIdentifier("MyCategoryId" + i.ToString(), content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
Console.WriteLine("Error: {0}", err);
}
else
{
Console.WriteLine("Notification Scheduled: {0}", request);
}
});
NSDate nsDate = DateToSet.AddMinutes(i).ToNSDate();
var dateAfterAddingAnInterval = NSCalendar.CurrentCalendar.DateByAddingUnit(NSCalendarUnit.Minute, 5, nsDate, NSCalendarOptions.None);
//if DateToSet is greater than current time, add that gap to the interval
double AdditionalTime = 0;
if (DateToSet.AddMinutes(i) > DateTime.Now)
{
AdditionalTime = (DateToSet.AddMinutes(i) - DateTime.Now).TotalSeconds;
}
var interval = dateAfterAddingAnInterval.GetSecondsSince(nsDate) + AdditionalTime;
UNMutableNotificationContent content1 = new UNMutableNotificationContent { Title = "Recurring Title", Body = "Recurring body " + i, Sound = UNNotificationSound.Default, CategoryIdentifier = "MyCategoryId" };
var IntervalTrigger = UNTimeIntervalNotificationTrigger.CreateTrigger(interval, true);
UNNotificationRequest RecurringReminderRequest = UNNotificationRequest.FromIdentifier("recurring_MyCategoryId" + i.ToString(), content1, IntervalTrigger);
UNUserNotificationCenter.Current.AddNotificationRequest(RecurringReminderRequest, (err) =>
{
if (err != null)
{
Console.WriteLine("Error: {0}", err);
}
else
{
Console.WriteLine("RecurringReminderRequest Notification Scheduled: {0}", RecurringReminderRequest);
}
});
}

Trying to implement timer and perform tasks every x seconds but the tasks seem to get delayed

I'm writing an app where a user specifies a length of time, length of an interval and a length of time in between intervals. I want to have a timer label showing the user the total time but then I also want to have a label showing the work status (recording if in the interval, break if between interval time and break end).
Heres an Example: Total time = 2 min, Interval = 20 seconds, Break = 10 seconds
In this example there will be 4 intervals. So from 0:00-0:19 I want to display "Recording" and then from 0:20-0:29 I want to display break and then from 0:30-0:49 I display "Recording" and 0:50-0:59 I display "Break" and so on. All while the timer counts the time.
So I thought this would be pretty straightforward but what seems to happen is the timer increments properly but after the 1st interval the label doesnt switch from break to recording until 0:31 or 0:32 so it looks a little delayed.
Here is the code I am using currently (Note obs is an object Im passing in that has data from user input).
int TotalInterval = obs.Interval + obs.Break;
int WorkingInterval = obs.Interval;
int NumberOfIntervals = (obs.Duration*60) / TotalInterval;
DateTime ObservationEnd = obs.DateCreated.AddMinutes(obs.Duration);
Timer.Text = "Starting Timer";
int minutes = 0;
int seconds = 0;
int InIntervalCounter = 0;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
// called every 1 second
Timer.Text = "Started";
if (ObservationEnd < DateTime.UtcNow)
{
Timer.Text = "Time Over";
Results.IsVisible = true;
return false;
}
else
{
seconds++;
InIntervalCounter++;
if (InIntervalCounter > WorkingInterval)
IntervalOrBreak.Text = "Break";
if (InIntervalCounter > TotalInterval)
{
IntervalOrBreak.Text = "Recording";
InIntervalCounter = 0;
}
Timer.Text = "Time: " + minutes + ":" + seconds.ToString("D2");
return true;
}
});
I'm pretty new to app development/xamarin so any help is greatly appreciated.
Try using simple Threads with Thead.sleep() like this:
final long delay_millis = 100;
Thread thread_something;
thread_something = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
long start_time = SystemClock.elapsedRealtime();
// Do some task
long time_need_for_delay = (start_time + delay_millis) - SystemClock.elapsedRealtime();
if(time_need_for_delay > 0)
thread_something.sleep(time_need_for_delay);
} catch (Exception e) { }
}
}
});
thread_something.start();
after the 1st interval the label doesnt switch from break to recording
until 0:31 or 0:32 so it looks a little delayed.
If you want to display break from 0:20-0:29 and display "Recording" from 0:30-0:49, I think the if statement should change to InIntervalCounter >= WorkingInterval and InIntervalCounter >= TotalInterval, InIntervalCounter > WorkingInterval may cause the 1 second delay.

make first iteration in loop same speed as the rest

I am trying to benchmark something.
I have a loop like
for (int i = 1; i <= 1000; i++)
{
Thing thing = createThing(i);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
It looks like the first iteration, i = 1, takes a significant amount of time longer than it should (several orders of magnitude) based on how long the others take to complete.
The second iteration also seems too long often, although less obviously.
I feel like this is because the loop causes caching of a lot of values, which hadn't been set up in the first iteration.
Is there a way I can get the first iteration, i = 1, to be as "fast" (overhead-wise) as the rest, so that I really am timing only (as best as possible) thing.ComputationallyExpensiveOp().
At the moment it's obvious that the first iteration is not an accurate reflection of thing.ComputationallyExpensiveOp().
I tried already moving a "warm up" initialisation above the loop, but that didn't work.
Thing thing = createThing(1);
thing.ComputationallyExpensiveOp();
for (int i = 1; i <= 1000; i++)
{
thing = createThing(i);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
I have been using such for-loops for decades. And I never experienced, that such a for-loop was the cause of a delay during the first iteration.
I don't know anything about your Thing implementation, but I am quite sure the cause of your delay lies there. Not in the loop.
Copying the whole loop body outside "fixed" it for me
Thing thing = createThing(1);
DateTime startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
TimeSpan elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + 1 + "\ttime = " + elapsed.TotalMilliseconds);
for (int i = 1; i <= 1000; i++)
{
thing = createThing(i);
startTime = DateTime.Now;
thing.ComputationallyExpensiveOp();
elapsed = DateTime.Now - startTime;
Console.WriteLine(String.Format("i = " + i + "\ttime = " + elapsed.TotalMilliseconds);
}
I'm not really sure of the cause, but now the first iteration has a runtime more like expected.

Countdown timer in javascript using setTimeout

i'm creating a countdown timer using jquery, i refered to a few example here and came out with the following codes. The problem is the time doesn't show, and i can't figure out what is wrong. Been stuck for almost 2 hours..
back code
var day = 1; //countdown time
var start = player.LastActive; // Use UtcNow instead of Now
var endTime = start.AddDays(day); //endTime is a member, not a local variable
Timespan remainingTime = endTime - DateTime.UtcNow;
my javascript
var endTime = '<%= remainingTime%>';
var startTime = '<%= DateTime.UtcNow %>'
$(document).load(function () {
countDown(endTime);
});
function countDown(endTime) {
if (endTime > 0) {
var d = document.getElementById("countDiv");
d.innerHTML = endTime;
setTimeout(function () { countDown(endTime - 1); }, 1000);
}
}
my html
<div id="countDiv" style="float:left;margin-top: 13px; margin-left:5px;"></div>
my goal is to show how long more, for a player to get his daily move : which is a day after the players lastactive time. Can someone enlighten me..thank u
use $(window).load
or
$(document).ready
but not $(document).load
and as you seem to use jquery, you can do
$(document).ready(function () {
countDown(endTime);
});
function countDown(endTime) {
if (endTime > 0) {
$('#countDiv').text(secondsToTime(endTime));
setTimeout(function () { countDown(endTime - 1); }, 1000);
}
}
function secondsToTime(secs)
{
var hours = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
return hours +':' + minutes + ':' + seconds;
}
for seconds to time, it's coming from
https://stackoverflow.com/a/6312999/961526 , you may take another version which you can find there.
see jsFiddle
Since your endtime is string in your javascript code, convert it integer first
try this
$(document).ready(function () {
countDown(parseInt(endTime));
});
ready, not load.
$(document).ready(function () {
countDown(endTime);
});
Or try this
$(function() {
countDown(endTime);
});
function countDown(parseInt(endTime)) {
if (endTime > 0) {
$('#countDiv').text(endTime);
setTimeout(function () { countDown(endTime - 1); }, 1000);
}
}

Faster alternative to DateTime.FromFileTime(fileTime).ToLocalTime().ToString()

While profiling my application I found that DateTime.FromFileTime(long fileTime) is slow.
Does anyone know of a fast managed equivalent or the windows file time format?
[EDIT]
I was able to get some speed gains doing the following:
var timeStr = FastTimeStringFormat(new DateTime(fileTime + 0x701ce1722770000L, DateTimeKind.Utc).ToLocalTime()); // + 0x701ce1722770000L is the offset needed to convert to UTC DateTime
For more speed but less safety (no intra-day daylight savings time checks), you can cache the ToLocalTime offset (long) and spare the more expensive expensive ToLocalTime() call.
On App Start:
long fileTimeOffset = DateTime.Today.Subtract(DateTime.Today.ToUniversalTime()).Ticks + 0x701ce1722770000L;
Then in your critical path:
var timeStr = FastTimeStringFormat(new DateTime(fileTime + fileTimeOffset));
As it turned out ToString is very expensive and the following is faster.
public static unsafe string FastTimeStringFormat(DateTime time)
{
// modified version from the following post:
// http://geekswithblogs.net/akraus1/archive/2006/04/23/76146.aspx
// this one is also more accurate because of true divide by 10, beware of less accurate versions that do not use division
char* FixedCharArray = stackalloc char[13];
int hour = time.Hour; // Cache property values
int minute = time.Minute;
int second = time.Second;
int ms = time.Millisecond;
// hour
FixedCharArray[0] = (Char)('0' + hour / 10);
FixedCharArray[1] = (Char)('0' + hour % 10);
FixedCharArray[2] = ':';
// minute
FixedCharArray[3] = (Char)('0' + minute / 10);
FixedCharArray[4] = (Char)('0' + minute % 10);
FixedCharArray[5] = ':';
// seconds
FixedCharArray[6] = (Char)('0' + second / 10);
FixedCharArray[7] = (Char)('0' + second % 10);
FixedCharArray[8] = '.';
// miliseconds
FixedCharArray[9] = (Char)('0' + ms / 100);
FixedCharArray[10] = (Char)('0' + ms % 100 / 10);
FixedCharArray[11] = (Char)('0' + ms % 10);
return new String(FixedCharArray);
}
DateTime.FromFileTime() is implemented in managed code, there are no P/Invoke calls involved.
The performance hit you're experiencing might come from the conversion to local time that is performed internally. Try using DateTime.FromFileTimeUtc() instead, if at all possible.

Categories

Resources