I'm creating a C# MVC project that uses Oracle Database. While trying to connect to the DB, I get following error:
ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found.
When I try to connect via SQL developer it works fine. Is there any way that I can solve this problem ?
NOTE: I'm using IIS express for testing
I was facing the same issue using ODP.NET for .NET Core on Pivotal Cloud Foundry. The core issue is missing timezone information.
Added a timezone by setting "TZ" environment variable for my instance. That fixed the issue for me.
Actually, this error because of some issue with application Oracle driver which you use and Oracle version of the DB.
NOTE: Please check Both of them and use Updated Oracle versions for your application.
ORA-01882: timezone region not found
Had the same problem in .Net Core 3.1 API with controllers.
had the error on debug, and solved it adding TZ on \Properties\launchSettings.json:
"Docker": {
...
"environmentVariables": {
"TZ": "WET"
}
}
This code does not provide an answer but it may help to find your problem.
The code is too big for a comment.
Please execute this program. What is the output? Where does it fail?
static void Main(string[] args)
{
Console.WriteLine("OracleGlobalization.TimeZone = {0}", Oracle.DataAccess.Client.OracleGlobalization.GetClientInfo().TimeZone);
Console.WriteLine(String.Empty);
Console.WriteLine("TimeZone.CurrentTimeZone.StandardName = {0}", TimeZone.CurrentTimeZone.StandardName);
Console.WriteLine("TimeZone.CurrentTimeZone.DaylightName = {0}", TimeZone.CurrentTimeZone.DaylightName);
Console.WriteLine(String.Empty);
Console.WriteLine("TimeZoneInfo.Local.DisplayName = {0}", TimeZoneInfo.Local.DisplayName);
Console.WriteLine("TimeZoneInfo.Local.Id = {0}", TimeZoneInfo.Local.Id);
Console.WriteLine("TimeZoneInfo.Local.StandardName = {0}", TimeZoneInfo.Local.StandardName);
Console.WriteLine("TimeZoneInfo.Local.DaylightName = {0}", TimeZoneInfo.Local.DaylightName);
Console.WriteLine(String.Empty);
var str = new Oracle.DataAccess.Client.OracleConnectionStringBuilder();
str.UserID = "<username>";
str.Password = "<password>";
str.DataSource = "<database name>";
using ( var con = new Oracle.DataAccess.Client.OracleConnection(str.ConnectionString) ) {
con.Open();
Console.WriteLine("Oracle.DataAccess: OracleConnection -> SessionInfo.TimeZone = {0}", con.GetSessionInfo().TimeZone);
Console.WriteLine("Oracle.DataAccess: Version = {0}", FileVersionInfo.GetVersionInfo(con.GetType().Assembly.Location).FileVersion.ToString());
var tz = new Oracle.DataAccess.Client.OracleCommand("SELECT SESSIONTIMEZONE FROM dual", con).ExecuteScalar();
Console.WriteLine("Oracle.DataAccess: SESSIONTIMEZONE = {0}", tz.ToString());
con.Close();
}
Console.WriteLine(String.Empty);
var strm = new Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder();
str.UserID = "<username>";
str.Password = "<password>";
str.DataSource = "<database name>";
using ( var con = new Oracle.ManagedDataAccess.Client.OracleConnection(str.ConnectionString) ) {
con.Open();
Console.WriteLine("Oracle.ManagedDataAccess: OracleConnection -> SessionInfo.TimeZone = {0}", con.GetSessionInfo().TimeZone);
Console.WriteLine("Oracle.ManagedDataAccess: Version = {0}", FileVersionInfo.GetVersionInfo(con.GetType().Assembly.Location).FileVersion.ToString());
var tz = new Oracle.ManagedDataAccess.Client.OracleCommand("SELECT SESSIONTIMEZONE FROM dual", con).ExecuteScalar();
Console.WriteLine("Oracle.ManagedDataAccess: SESSIONTIMEZONE = {0}", tz.ToString());
con.Close();
}
}
Update
According to your profile you are based in Sri Lanka. Time zone of Sri Lanka seems to be fairly "volatile", see text from IANA TimeZone Database:
Sri Lanka
From Paul Eggert (2013-02-21):
Milne says "Madras mean time use from May 1, 1898. Prior to this Colombo
mean time, 5h. 4m. 21.9s. F., was used." But 5:04:21.9 differs considerably
from Colombo's meridian 5:19:24, so for now ignore Milne and stick with
Shanks and Pottenger.
From Paul Eggert (1996-09-03):
"Sri Lanka advances clock by an hour to avoid blackout"
(http://www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
no longer available as of 1999-08-17)
reported "the country's standard time will be put forward by one hour at
midnight Friday (1830 GMT) 'in the light of the present power crisis'."
From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
by Shamindra in Daily News - Hot News Section
(1996-10-26):
With effect from 12.30 a.m. on 26th October 1996
Sri Lanka will be six (06) hours ahead of GMT.
From Jesper Nørgaard Welen (2006-04-14), quoting Sri Lanka News Online
http://news.sinhalaya.com/wmview.php?ArtID=11002 (2006-04-13):
0030 hrs on April 15, 2006 (midnight of April 14, 2006 +30 minutes)
at present, become 2400 hours of April 14, 2006 (midnight of April 14, 2006).
From Peter Apps and Ranga Sirila of Reuters (2006-04-12) in:
http://today.reuters.co.uk/news/newsArticle.aspx?type=scienceNews&storyID=2006-04-12T172228Z_01_COL295762_RTRIDST_0_SCIENCE-SRILANKA-TIME-DC.XML
[The Tamil Tigers] never accepted the original 1996 time change and simply
kept their clocks set five and a half hours ahead of Greenwich Mean
Time (GMT), in line with neighbor India.
From Paul Eggert (2006-04-18):
People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
as that zone has agreed with the Tamil areas since our cutoff date of 1970.
From Sadika Sumanapala (2016-10-19):
According to http://www.sltime.org (maintained by Measurement Units,
Standards & Services Department, Sri Lanka) abbreviation for Sri Lanka
standard time is SLST.
From Paul Eggert (2016-10-18):
"SLST" seems to be reasonably recent and rarely-used outside time
zone nerd sources. I searched Google News and found three uses of
it in the International Business Times of India in February and
March of this year when discussing cricket match times, but nothing
since then (though there has been a lot of cricket) and nothing in
other English-language news sources. Our old abbreviation "LKT" is
even worse. For now, let's use a numeric abbreviation; we can
switch to "SLST" if it catches on.
I assume your database does not recognize your current local time zone of your computer. There might be three possible solutions:
Change your computer locale settings to a more stable one, e.g. India
Update database with latest version of time zone file, see Upgrading the Time Zone File and Timestamp with Time Zone Data
In case you use the ODP.NET Unmanaged driver Oracle.DataAccess.dll (unfortunately you did not tell us) you can set ORA_SDTZ environment variable or Registry key HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_<Oracle home name>\ORA_SDTZ / HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_<Oracle home name>\ORA_SDTZ to desired time zone value. Note, the ODP.NET Managed Driver does not read this Registry values.
According to this straight from an Oracle employee, set UseHourOffsetForUnsupportedTimezone property for the Connection to true, before opening it.
con.UseHourOffsetForUnsupportedTimezone = true;
con.Open();
This worked for me as I did not have control on the OracleDB server, and in my crossplatform application, the environment variable usage was not being consistent across linux distros. I had ran Weinfried's snippet on all of them to test and there was no timezone descrepency with OracleDB in my case(both on UTC, no DST) but was still failing on the same plank.
According to this and this:
In C:\Program Files\datamodeler 3\datamodeler\bin\datamodeler.conf add
AddVMOption -Duser.timezone="+02:00"
Related
I have a .NET Core 2.2 web app running inside a docker-compose app. I'm saving different UTC time stamps to a database, like this:
//set asked state on question
Question questionInDb = c.Questions.Single(x => x.Id == id);
questionInDb.Asked = true;
questionInDb.AskTime = DateTime.UtcNow;
c.SaveChanges();
In the apppsettings.json I have a section for my app's settings, containing the locale the application is supposed to run on. I set the CultureInfo.CurrentCulture like so:
//get locale from settings, defaulting to de-DE
string locale = "de-DE";
locale = Configuration.GetValue<string>("AppSettings:Locale");
var ci = new CultureInfo(locale, false);
//actually setting locale
CultureInfo.CurrentCulture = ci;
I set up my Entity Framework to set all DateTimes to DateTimeKind.Utc, so the app knows the DateTimes it gets are all UTC.
Now, when displaying the time on a view, it's not the right hour. In the view.cshtml I'm using #q.AskTime.ToString("HH:mm:ss dd.MM.yy"), but it always returns the exact value from the database. It's supposed to show one hour more.
I even tried setting the container's timezone to CET (Centran Euopean Time) using ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone (in my docker-compose I set the environment variable TZ to Europe/Berlin).
I'm out of ideas.
Cultures (also known as locales) are used for displaying and formatting data and is a different concept than timezones. You can find and create a specific TimeZoneInfo from a timezone name and convert an UTC date and time using the ConvertTimeFromUtc() method.
Keep in mind that different operating systems use different timezone names. For example you can use Europe/Berlin for Linux and Central Europe Standard Time for Windows.
Example:
TimeZoneInfo tz;
try
{
// Linux
tz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
}
catch (TimeZoneNotFoundException)
{
try
{
// Windows
tz = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");
}
catch (TimeZoneNotFoundException)
{
// Fallback to UTC
tz = TimeZoneInfo.Utc;
}
}
var converted = tz.ConvertTimeFromUtc(DateTime.UtcNow);
I'm setting up a calendar invite email using ical.net. Sending out a non-recurring event seems to work perfectly: I set the start and end date like this
iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value.AddMinutes(model.DurationMins.Value), DateTimeKind.Utc));
when the email arrives, the time zone has been converted to the recipients timezone (The timezone is -7, the eventTime is 4pm and the duration is 3 hours)
However, when I take this same exact code and add this line to it
IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = DateTime.SpecifyKind(model.endDate.Value.AddDays(1), DateTimeKind.Utc)
};
iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };
Suddenly my timezone is no longer converted when the email is received (The timezone is -7, the eventTime is 4pm and the duration is 3 hours. The endDate is on the 28th)
I need the DateTime to be displayed to the user in their own timezone and I need to display recurring events from the eventTime to the endDate
It may also be useful to note that I do not have a timezone property specified on Calendar as it was causing the sent email to show a "not supported calendar message" in outlook. Before I removed it, it looked like this
iCal.AddTimeZone(new VTimeZone("UTC"));
when I opened ical files that had this time zone specified, they seemed to work correctly for multi day events, but as I need them to appear in outlook with the accept/decline/tentative buttons, it is out of the question to add it back
i've also tried specifying datetimes like this
iCalEvent.DtStart = new CalDateTime(leEvent.EventTime.Value, "UTC");
but nothing changed
EDIT: I now understand that the issue is due to a recurring event needing a timezone as specified here, but I'm not quite sure where the timezone needs to be specified. I went back to adding the vTimeZone back in and validating it through this site, and it appears that the iCal file is missing the standard/daylight section inside of the timezone block
I have also tried specifying the timezone as GMT and specifying the timezone as "\"America/Phoenix\"" so that the tzid came out as TZID:"America/Phoenix" (with quotes in the ical file.
This is my code at the moment that causes the issue.
iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtStart.Value.AddMinutes(model.DurationMins.Value));
if (model.EndDate.HasValue)
{
IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = DateTime.SpecifyKind(model.MaxDate.Value, DateTimeKind.Utc).ToLocalTime()
};
iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };
iCalEvent.DtStart = new CalDateTime(iCalEvent.DtStart.Value.ToLocalTime(), "America/Phoenix");
iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtEnd.Value.ToLocalTime(), "America/Phoenix");
iCal.AddTimeZone(new VTimeZone("America/Phoenix"));
}
I'm not quite sure what needs to happen to correct the standard/daylight ical error from this point.
FINAL EDIT:
after reading through this post, I found that this issue has already been solved as of last november. I checked the version we had in our project and it turned out some genius just copied the dll straight in without setting it up through nuget (and a version from several years ago no less). I grabbed the latest version and this time specifying the timezone caused no issues in outlook. I'm still experimenting with addTimeZone and addLocalTimeZone but I'm definitely on the right track. Thank you to rianjs for this extremely useful library. I don't know how I would possible work with this crazy calendar standard without it.
A recurring event is always relative to the sender's timezone (or rather to the event location), and not to the recipient's timezone, because of daylight saving changes which may happen at different time between the organiser and the various recipients.
So in most cases you want to use a meaningful timezone in the event (i.e. not UTC).
Then Outlook is simply showing that the event is indeed happening according to the given timezone. This is an indication that the event may not always be at the same time of day for the recipient.
Since this took me so long to figure out, I might as well share my solution in case anyone else runs into this problem and finds this.
I defined the DtStart/DtEnd with two datetimes that had kind utc
calendarEvent.DtStart = new CalDateTime(model.EventTime.Value);
calendarEvent.DtEnd = new CalDateTime(model.EventTime.Value.AddMinutes(model.DurationMins.Value));
which worked great for single day events, but with multidays I ended up doing this
if (model.EndDate.HasValue)
{
RecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = model.EndDate.Value //has kind: Utc
};
var timezoneOffsetString = "Etc/GMT";
if (timezoneOffset > 0) //client time zone offset, calculated through js
{
timezoneOffsetString += "-" + timezoneOffset;
}
else if (timezoneOffset < 0)
{
timezoneOffsetString += "+" + (-1 * timezoneOffset);
}
calendar.AddTimeZone(timezoneOffsetString);
calendarEvent.DtStart = calendarEvent.DtStart.ToTimeZone(timezoneOffsetString);
calendarEvent.DtEnd = calendarEvent.DtEnd.ToTimeZone(timezoneOffsetString);
calendarEvent.RecurrenceRules = new List<RecurrencePattern> { recurrence };
}
It's not fullproof as some places may have weird dst problems, but nodatime was treating the "America/Phoenix" tzid as an LMT time, which was giving me a time that was like 28 minutes off... Besides, treating all dates as GMT is closer to the implementation we have in the rest of our app so it worked for my situation
This solution gave me the idea to piece together the Etc/GMT stuff.
I am logging time in many places
If Request.DynamicSettings.AirlineSettings.AirlineGeneralSettings.TimeLogEnabled Then
StartTime = DateTime.Now
LogTime(Reflection.MethodBase.GetCurrentMethod.DeclaringType.FullName, Reflection.MethodBase.GetCurrentMethod.Name, StartTime, DateTime.Now, "AB-SCR(I)", 0,)
End If
all places i have used
DateTime.Now
I am facing an issue now,
I am currently hosting this in a gulf server, GMT +4:00
I need to host this same project for another country at Gmt +3Gmt
for this hosting i need time to be logged using that country's local time.
Is there any way to do this, without having to modify each and every line of my code.
i have seen this article timzone with asp.net but as my service is already up i have a lot of codes to change, i am looking for a simpler solution.
thanks.
A few things:
You cannot change the time zone in the IIS configuration or web.config. This is not an IIS problem, but rather a problem in your application code.
DateTime.Now should never be used in a server side application, such as an ASP.Net web application. Read The case against DateTime.Now.
If you are just timing how long something takes to run, don't use DateTime at all. Instead, use System.Diagnostics.Stopwatch.
Stopwatch sw = Stopwatch.StartNew();
// ...do some work ...
sw.Stop();
TimeSpan elapsed = sw.Elapsed; // how long it took will be in the Elapsed property
If you actually want the current time in a specific time zone, then you need to know the time zone identifier. (GMT+4 and GMT+3 are not time zones, but rather time zone offsets see "Time Zone != Offset" in the timezone tag wiki.) You can see a list of Windows time zones by using TimeZoneInfo.GetSystemTimeZones(), or by calling tzutil /l on the command line.
Then in your application:
string tz = "Arabian Standard Time";
DateTime now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz);
You should probably refactor your code such that this is done inside your LogTime method. Then you will have only one place to set the time zone for your application.
I´m having trouble when working with dates in my Web MVC project. It is running in my local IIS.
The problem is, I live in Brazil, Rio de Janeiro, so according to a this my TimeZone is
E. South America Standard Time
That means Brasilia with GMT-3. And it is perfect and correct.
But when running my unit test in NCrunch, for the code above:
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
var zone = TimeZone.CurrentTimeZone;
var time = zone.GetDaylightChanges(DateTime.Today.Year);
var start = time.Start;
var end = time.End;
var offset = zone.GetUtcOffset(DateTime.Now);
I ´m receiving the following results:
zone.DaylightName = "E. South America Daylight Time" (CORRECT)
time.Start = {18/10/2014 23:59:59} (CORRECT FOR 2014)
time.End = {15/02/2014 23:59:59} (CORRECT FOR 2014)
offset = {-2:00:00} (WRONT, it is -3) -> it would be right if there was no daylight saving time
TimeZone.IsDaylightSavingTime(DateTime.Now) = true
The problem is that when I send it to Postgres DB it saves as timestampZ so, it saves correct
for example 01/01/01 01:01:01 -3
But then when retrieving from database, it comes the mistake, because of the wrong offset I get
01/01/01 02:01:01 -3
It is runnin in local IIS but it should use the local computer time, right? If I go to my computer settings is is correct (Brasilia Time, GMT-3)
How should I proceed?
Thanks in regards,
Edit
Actually the problem is in my PostgresSQL. It is saving the current time with offset -3 instead of -2 and that is all the problem. When i get it back in server it adds one hour...
How do I enable DST in Postgres?!?
How can I get the Original Install Date of the Windows using C#?
From this website, using the registry rather than WMI (untested):
public static DateTime GetWindowsInstallationDateTime(string computerName)
{
Microsoft.Win32.RegistryKey key = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, computerName);
key = key.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion", false);
if (key != null)
{
DateTime installDate =
DateTime.FromFileTimeUtc(
Convert.ToInt64(
key.GetValue("InstallDate").ToString()));
return installDate;
}
return DateTime.MinValue;
}
The HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate is the Windows InstallDate using a Unix timestamp, but technically it's the wrong date.
Let me explain;
The definition of UNIX timestamp is time zone independent. The UNIX timestamp is defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970 and not counting leap seconds.
In other words, if you have installed you computer in Seattle, WA and moved to New York,NY the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate will give you the date in NY timezone, not in Seattle timezone where Windows was original installed. It's the wrong date, it doesn't store timezone where the computer was initially installed.
Solution
Change you computer time zone (right-click on you clock->Adjust date/time->Adjust time zone) to the time zone where windows was installed, or first turned on. Then run systeminfo.exe find /i "Original Install Date"
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate but you have add the time zone where windows was installed, or first turned on.