Custom output cache mvc4 - c#

I am trying to utilise caching on an MVC4 project and I have the following attribute set on my homepage:
[OutputCache(Location=OutputCacheLocation.ServerAndClient,Duration=14400)]
This works fine, however the duration is causing me an issue. What I need is for the cache to expire on the start of a new day (midnight each day). I could set the duration to be 24 hours however this does not solve my problem with my page having new content on the start of each day. I have explored the vary by param method and I understand that I can append the date to the URL but this is very messy. Does anyone know an alternative?
Thanks in advance

A solution will be to extend the OutputCacheAttribute and to create a new one that works for midnight because you can set Duration in constructor.
public class OutputCacheMidnightAttribute : OutputCacheAttribute
{
public OutputCacheMidnightAttribute()
{
// remaining time to midnight
Duration = (int)((new TimeSpan(24, 0, 0)) - DateTime.Now.TimeOfDay).TotalSeconds;
}
}
And you use it like this
[OutputCacheMidnight(Location=OutputCacheLocation.ServerAndClient)]

Related

How can I reset the scores of the game on certain days using firebase in "Unity"

How can I reset the scores of the game on certain days using firebase in "Unity"
I want the scores I marked in the picture to be reset every day, every week, at the end of every month, in short, when their time comes. How can I do this?
What you want to look into is the Cloud Functions feature called scheduled functions.
If you're only familiar with Unity, you'll want to follow this getting started guide for more details. The basic gist of it is that you'll create a tiny snippet of JavaScript that runs at a fixed schedule and lets you perform some administrative tasks on your database.
I'll try to encapsulate the basic setup:
install Node
run npm install -g firebase-tools
create a directory where you want to work on functions - you probably want to to do this outside of your Unity directory
run firebase login to log in to the Firebase CLI
run firebase init (or firebase init functions) and follow the steps in the wizard to create some functions code to test
when you're ready to use them in your game, you can use firebase deploy to send them off to the cloud.
From the Scheduled functions doc page, you can see this example of how to run a function every day:
exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 11 * * *')
.timeZone('America/New_York') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) => {
console.log('This will be run every day at 11:05 AM Eastern!');
return null;
});
You can use these with the Node Admin SDK. Something like:
// Import Admin SDK
var admin = require("firebase-admin");
// Get a database reference to our blog
var db = admin.database();
exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 11 * * *')
.timeZone('America/New_York') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) => {
db.ref(`users/${user_id}/`).update({userGameScore: 0, userMonthScore: 0, userScore: 0, userWeeklyScore: 0});
return null;
});
Of course, here I'm not iterating over user ids &c.
One final note: this is a very literal interpretation and answer to your question. It may be easier to (and save you some money if your game scales up) to write a score and timestamp (maybe using ServerValue.Timestamp) together into your database and just cause the scores to appear zeroed out as client logic. I would personally first try taking this approach and abandon it if it felt like it was getting too complex.

Get PC TimeZone on C#

Im currently developing on asp - c# as a backend code. I want to get the current timezone that was set on the PC.
The below code are still identifying what is the correct timezone of my current area (+8GMT) even though I already changed my PC timezone settings into another timezone.
What I want is to get the timezone offset specified on the PC date settings. Can anyone help me on this. Below is my code so far.
public TimeSpan currentOffset;
public DateTime utc;
public DateTime local;
this.utc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, TimeZoneInfo.Utc.Id);
this.local = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, TimeZoneInfo.Local.Id);
this.currentOffset = this.local.Subtract(this.utc);
In addition to David Haney's answer.
TimeZoneInfo is caching data after first call so any changes in PC settings will not affect your application if it is already running.
You should call method:
TimeZoneInfo.ClearCachedData();
to refresh this cache.
So this one will work in your case:
TimeZoneInfo.ClearCachedData();
var offsetTimespan = DateTimeOffset.Now.Offset;
var offsetInHours = offsetTimespan.TotalHours;
You're making your life harder than it needs to be. :)
Use DateTimeOffset: http://msdn.microsoft.com/en-us/library/system.datetimeoffset.now%28v=vs.110%29.aspx
var now = DateTimeOffset.Now;
This will include the time zone offset information as well.

Inconsistencies in DateTime between local machine and Azure

I have an app hosted in an Azure Website. When using the hosted application, the DateTimes are displayed and saved properly. When I run the application locally, and pull the data from the Azure SQL database, I get very weird results. Every datetime seems to be 6 hours off.
If I'm on my local box and I pull data from the server, all datetimes are displayed as actual+6 hours.
If I then, from local box, post something to Azure SQL, the time gets saved as actual-6hrs.
An example of the reads/writes I'm talking about:
Write:
var chatMessage = new ChatMessage() {
DatePosted = DateTime.Now
};
db.ChatMessages.Add(chatMessage);
Read:
// get chatMessage from db
messageVm.DateIndicator = DateUtilities.GetFriendlyDate(chatMessage.DatePosted);
// GetFriendlyDate is:
public static string GetFriendlyDate(DateTime? postDate) {
if (postDate == null) {
return null;
}
string stringy = string.Empty;
TimeSpan diff = DateTime.Now.Subtract((DateTime) postDate);
double days = diff.Days;
double hours = diff.Hours + days * 24;
double minutes = diff.Minutes + hours * 60;
if (minutes <= 1) {
return "Just Now";
}
// etc
}
So in the above Read - if I'm running the app locally and accessing Azure SQL, content posted 5 hours ago is being displayed as posted "Just Now", and if I save a new message, the hosted application displays the time as 6 hours ago (when it should be "just now").
Splitting the logic (local) from the db (azure) is obviously the cause of this - but is this an indication that I'm not handling DateTimes properly? If so, what am I doing wrong?
You're in a different time zone. Use DateTime in UTC, or better yet avoid all the oddities of that and use DateTimeOffset.
Unlike .NET's DateTime type, databases don't have a "Kind" that indicates if they're a local or UTC date. This makes them really easy to use inconsistently and not even realize it. DateTimeOffset stores an offset from UTC, so it does not have the same problem.
Try using DateTime.UtcNow rather than DateTime.Now

File creation time in C#

I need to get when a file was created - I have tried using:
FileInfo fi = new FileInfo(FilePath);
var creationTime = fi.CreationTimeUtc;
and
var creationTime = File.GetCreationTimeUtc(FilePath);
Both methods generally return the wrong creation time - I guess it is being cached somewhere.
The file is deleted and re-created with the same name and I need to know when/if it has been re-created (by checking if the created date/time has changed) - I had planned to do this by seeing it the file creation time had changed but I have found this to be inaccurate.
I'm working on Win 7 and if I check File Explorer it shows the new file creation time correctly.
I have also tried using the FileSystemWatcher but it doesn't entirely work for my use case. E.g. if my program is not running, the FileSystemWatcher is not running, so when my program starts up again I don't know if the file has been deleted and recreated or not.
I've seen MSDN http://msdn.microsoft.com/en-us/library/system.io.file.getcreationtime.aspx where it says:
This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by the operating system.
But I have also tried using their alternative suggestion and setting the SetCreationDate after creating a new file but I also find that this doesn't work. See test below:
[Test]
public void FileDateTimeCreatedTest()
{
var binPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
var fullFilePath = Path.Combine(binPath, "Resources", "FileCreatedDatetimeTest.txt");
var fullFilePathUri = new Uri(fullFilePath);
var dateFormatted = "2013-08-17T15:31:29.0000000Z"; // this is a UTC string
DateTime expectedResult = DateTime.MinValue;
if (DateTime.TryParseExact(dateFormatted, "o", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out expectedResult)) // we expect the saved datetime to be in UTC.
{
}
File.Create(fullFilePathUri.LocalPath);
Thread.Sleep(1000); // give the file creation a chance to release any lock
File.SetCreationTimeUtc(fullFilePathUri.LocalPath, expectedResult); // physically check what time this puts on the file. It should get the local time 16:31:29 local
Thread.Sleep(2000);
var actualUtcTimeFromFile = File.GetCreationTimeUtc(fullFilePathUri.LocalPath);
Assert.AreEqual(expectedResult.ToUniversalTime(), actualUtcTimeFromFile.ToUniversalTime());
// clean up
if (File.Exists(fullFilePathUri.LocalPath))
File.Delete(fullFilePathUri.LocalPath);
}
Any help much appreciated.
You need to use Refresh:
FileSystemInfo.Refresh takes a snapshot of the file from the current
file system. Refresh cannot correct the underlying file system even if
the file system returns incorrect or outdated information. This can
happen on platforms such as Windows 98.
Calls must be made to Refresh before attempting to get the attribute
information, or the information will be outdated.
The key bits from MSDN indicate that it takes a snapshot and attribute information..will be outdated.
Try using FileInfo and Refresh method of it
fileInfo.Refresh();
var created = fileInfo.CreationTime;
this should work
File.Create(fullFilePathUri.LocalPath);
Thread.Sleep(1000); // give the file creation a chance to release any lock
That is not how you do it. File.Create creates stream writer which should be closed to release the lock without any waiting. If you find yourself using Thread.Sleep, you will often find that you are doing something wrong.
If the file described in the path parameter does not exist, this method returns 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC), adjusted to local time.
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.getcreationtime?view=netframework-4.8

C# P/Invoke Attribute

New to C# Compact edition 6.5. I am trying to set the datetime on a file which seems to be off by 5 hours from the actual system time. I am doing only this to create the file:
FileStream fs= File.Create(name);
Just doing this the Created date is 5 hours ahead...if I try and set the CreationTime I get a compile error saying the Attribute is Readonly, seriously?
FileInfo fi = new FileInfo(name);
fi.CreationTime = date;
So my question is since I am new to C# how do you get access to a "readonly" Attribute in the CE framework? I see mentioning of P/Invoke but seems to work on methods only and not attributes. Anyone can given a quick demo on how to do this?
I've tried this solution and still get the file writing UTC even though I send it the current local time
I just ran this:
[MTAThread]
static void Main()
{
var name = "\\foo.txt";
var info = new FileInfo(name);
using (info.Create()) { }
info.Refresh();
var createTime = info.CreationTime;
var now = DateTime.Now;
var delta = now - createTime;
Debug.WriteLine(delta.ToString());
}
And got this output:
00:00:00.0140000
Which seems to be correct to me.
You can't modify the CreationTime of a file. It's set once and only once when the file is created. If you're willing to use P/Invoke to set the time, you can check out this similar question - c# - Change file LastWriteDate in Compact Framework
Instead of hacking the problem, though, you should fix the root cause. If there's an issue with the creation time of the file, I would consider checking your system's time settings (including timezone).

Categories