webForumDet fria alternativet

Konvertera till datum från strängformat

.NET

7 svar · 301 visningar · startad av Pace

Medlem sedan juni 20019 024 inlägg
Frågan#1

Jag har datum i formatet

Wed, 22 Sep 2004 11:00:00 +0100

alltså RFC822 för att vara exakt, som kommer från en RSS-feed.

Problemet är att jag inte vet hur jag gör om det till ett DateTime-objekt (DateTime.Parse gillar inte datumformatet...). Hur göra?

Medlem sedan nov. 20022 355 inlägg
#2

Hm, kan du inte parsa upp strängen till ett format som datetime "gillar" eller måste det vara i ditt format från rss-strömmen?

Medlem sedan maj 20021 466 inlägg
#3

.NET har en funktion för det men den fungerar inte fullständigt.
Därför har jag tidigare gjort en klass för det. Den kanske inte är perfekt men den fungerar.

	public class MIMETime
	{
		static readonly string[] Days = new string[]
		{
			"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
		};

		static readonly string[] Months = new string[]
		{
			"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
		};

		#region TimeZones
		struct TimeZoneData
		{
			public TimeZoneData(string name, string offset)
			{
				Name = name; Offset = offset;
			}
			public string Name, Offset;
		}
		static TimeZoneData[] TimeZones = new TimeZoneData[]
		{
			new TimeZoneData("ACDT", "+1030"),    // Australian Central Daylight
			new TimeZoneData("ACST", "+0930"),    // Australian Central Standard
			new TimeZoneData("ADT",  "-0300"),    // (US) Atlantic Daylight
			new TimeZoneData("AEDT", "+1100"),    // Australian East Daylight
			new TimeZoneData("AEST", "+1000"),    // Australian East Standard
			new TimeZoneData("AHDT", "-0900"),
			new TimeZoneData("AHST", "-1000"),
			new TimeZoneData("AST",  "-0400"),    // (US) Atlantic Standard
			new TimeZoneData("AT",   "-0200"),    // Azores
			new TimeZoneData("AWDT", "+0900"),    // Australian West Daylight
			new TimeZoneData("AWST", "+0800"),    // Australian West Standard
			new TimeZoneData("BAT",  "+0300"),    // Bhagdad
			new TimeZoneData("BDST", "+0200"),    // British Double Summer
			new TimeZoneData("BET",  "-1100"),    // Bering Standard
			new TimeZoneData("BST",  "-0300"),    // Brazil Standard
			//   "BST",  "+0100"),    // British Summer
			new TimeZoneData("BT",   "+0300"),    // Baghdad
			new TimeZoneData("BZT2", "-0300"),    // Brazil Zone 2
			new TimeZoneData("CADT", "+1030"),    // Central Australian Daylight
			new TimeZoneData("CAST", "+0930"),    // Central Australian Standard
			new TimeZoneData("CAT",  "-1000"),    // Central Alaska
			new TimeZoneData("CCT",  "+0800"),    // China Coast
			new TimeZoneData("CDT",  "-0500"),    // (US) Central Daylight
			new TimeZoneData("CED",  "+0200"),    // Central European Daylight
			new TimeZoneData("CET",  "+0100"),    // Central European
			new TimeZoneData("CST",  "-0600"),    // (US) Central Standard
			new TimeZoneData("EAST", "+1000"),    // Eastern Australian Standard
			new TimeZoneData("EDT",  "-0400"),    // (US) Eastern Daylight
			new TimeZoneData("EED",  "+0300"),    // Eastern European Daylight
			new TimeZoneData("EET",  "+0200"),    // Eastern Europe
			new TimeZoneData("EEST", "+0300"),    // Eastern Europe Summer
			new TimeZoneData("EST",  "-0500"),    // (US) Eastern Standard
			new TimeZoneData("FST",  "+0200"),    // French Summer
			new TimeZoneData("FWT",  "+0100"),    // French Winter
			new TimeZoneData("GMT",  "+0000"),    // Greenwich Mean
			new TimeZoneData("GST",  "+1000"),    // Guam Standard
			//   "GST",  "-0300"),    // Greenland Standard
			new TimeZoneData("HDT",  "-0900"),    // Hawaii Daylight
			new TimeZoneData("HST",  "-1000"),    // Hawaii Standard
			new TimeZoneData("IDLE", "+1200"),    // Internation Date Line East
			new TimeZoneData("IDLW", "-1200"),    // Internation Date Line West
			new TimeZoneData("IST",  "+0530"),    // Indian Standard
			new TimeZoneData("IT",   "+0330"),    // Iran
			new TimeZoneData("JST",  "+0900"),    // Japan Standard
			new TimeZoneData("JT",   "+0700"),    // Java
			new TimeZoneData("MDT",  "-0600"),    // (US) Mountain Daylight
			new TimeZoneData("MED",  "+0200"),    // Middle European Daylight
			new TimeZoneData("MET",  "+0100"),    // Middle European
			new TimeZoneData("MEST", "+0200"),    // Middle European Summer
			new TimeZoneData("MEWT", "+0100"),    // Middle European Winter
			new TimeZoneData("MST",  "-0700"),    // (US) Mountain Standard
			new TimeZoneData("MT",   "+0800"),    // Moluccas
			new TimeZoneData("NDT",  "-0230"),    // Newfoundland Daylight
			new TimeZoneData("NFT",  "-0330"),    // Newfoundland
			new TimeZoneData("NT",   "-1100"),    // Nome
			new TimeZoneData("NST",  "+0630"),    // North Sumatra
			//   "NST",  "-0330"),    // Newfoundland Standard
			new TimeZoneData("NZ",   "+1100"),    // New Zealand 
			new TimeZoneData("NZST", "+1200"),    // New Zealand Standard  //-1300 NEW ZEALAND STD. SUMMER
			new TimeZoneData("NZDT", "+1300"),    // New Zealand Daylight  
			new TimeZoneData("NZT",  "+1200"),    // New Zealand           //NEW ZEALAND STD.
			new TimeZoneData("PDT",  "-0700"),    // (US) Pacific Daylight
			new TimeZoneData("PST",  "-0800"),    // (US) Pacific Standard
			new TimeZoneData("ROK",  "+0900"),    // Republic of Korea
			new TimeZoneData("SAD",  "+1000"),    // South Australia Daylight
			new TimeZoneData("SAST", "+0900"),    // South Australia Standard
			new TimeZoneData("SAT",  "+0900"),    // South Australia Standard
			new TimeZoneData("SDT",  "+1000"),    // South Australia Daylight
			new TimeZoneData("SST",  "+0200"),    // Swedish Summer
			new TimeZoneData("SWT",  "+0100"),    // Swedish Winter
			new TimeZoneData("USZ3", "+0400"),    // USSR Zone 3
			new TimeZoneData("USZ4", "+0500"),    // USSR Zone 4
			new TimeZoneData("USZ5", "+0600"),    // USSR Zone 5
			new TimeZoneData("USZ6", "+0700"),    // USSR Zone 6
			new TimeZoneData("UT",   "+0000"),    // Universal Coordinated
			new TimeZoneData("UTC",  "+0000"),    // Universal Coordinated
			new TimeZoneData("UZ10", "+1100"),    // USSR Zone 10
			new TimeZoneData("WAT",  "-0100"),    // West Africa
			new TimeZoneData("WET",  "-0000"),    // West European
			new TimeZoneData("WST",  "+0800"),    // West Australian Standard
			new TimeZoneData("YDT",  "-0800"),    // Yukon Daylight
			new TimeZoneData("YST",  "-0900"),    // Yukon Standard
			new TimeZoneData("ZP4",  "+0400"),    // USSR Zone 3
			new TimeZoneData("ZP5",  "+0500"),    // USSR Zone 4
			new TimeZoneData("ZP6",  "+0600"),    // USSR Zone 5
		};
		#endregion

		static string GetField(string data, ref int pos)
		{
			while(!char.IsLetterOrDigit(data[pos]))
				pos++;
			int start = pos;
			while(char.IsLetterOrDigit(data[pos]))
				pos++;
			return data.Substring(start, pos - start);
		}

		public static DateTime Parse(string data)
		{
			try
			{
				int pos = 0;
				// Get fields (pretty error safe)
				string fweekday, fday, fmonth, fyear, fhour, fminute, fsecond, fzone;
				fweekday = GetField(data, ref pos);
				if(char.IsNumber(fweekday[0])) // Weekday is optional, check if day
					fday = fweekday;
				else
					fday = GetField(data, ref pos);
				fmonth = GetField(data, ref pos);
				fyear = GetField(data, ref pos);
				fhour = GetField(data, ref pos);
				fminute = GetField(data, ref pos);
				fsecond = GetField(data, ref pos);
				fzone = data.Substring(pos).Trim();

				int year, month = 0;

				// Parse year. 0-79: 20xx, 80-99: 19xx
				year = int.Parse(fyear);
				if(year < 80) year += 2000;
				else if(year < 100) year += 1900;

				// Parse month
				for(int i = 0; i < Months.Length; i++)
					if(Months[i] == fmonth)
					{
						month = i + 1;
						break;
					}

				// Create time
				DateTime time = new DateTime(year, month, int.Parse(fday), int.Parse(fhour), int.Parse(fminute), int.Parse(fsecond));

				if(char.IsLetter(fzone[0]))
				{
					foreach(TimeZoneData zone in TimeZones)
						if(zone.Name == fzone)
						{
							fzone = zone.Offset;
							break;
						}
				}

				// Adjust for TimeZoneData
				if(fzone[0] == '+' || fzone[0] == '-' || char.IsNumber(fzone[0]))
				{
					bool add = !(fzone[0] == '-');
					int hour = int.Parse(fzone.Substring(1, 2));
					int minute = int.Parse(fzone.Substring(3, 2));
					TimeSpan span = new TimeSpan(hour, minute, 0);
					if(add) // East of GMT
						time = time.Subtract(span);
					else // West of GMT
						time = time.Add(span);
				}
				else if(fzone == "GMT" || fzone == "UT")
				{
					time = time.ToLocalTime();
				}
				return time;
			}
			catch
			{
				throw new Exception("Invalid time format.");
			}
		}

		public static string Format()
		{
			return Format(DateTime.Now);
		}
		public static string Format(DateTime time)
		{
			TimeSpan span = TimeZone.CurrentTimeZone.GetUtcOffset(time);
			string zone = string.Format("{0}{1:00}{2:00}", span.Ticks < 0 ? '-' : '+', Math.Abs(span.Hours), Math.Abs(span.Minutes));

			return string.Format("{0}, {1} {2} {3} {4:00}:{5:00}:{6:00} {7}",
				Days[(int)time.DayOfWeek], time.Day, Months[time.Month - 1],
				time.Year, time.Hour, time.Minute, time.Second, zone);
		}

	}
Medlem sedan juni 20019 024 inlägg
#4

Mc Fetto skrev:

Hm, kan du inte parsa upp strängen till ett format som datetime "gillar" eller måste det vara i ditt format från rss-strömmen?

Datum i RSS 2.0 ska vara i RFC822 så det är inget man kan göra något åt. Då får man utveckla 3.0, vilket jag inte är kompetent nog att göra. :e

Jag tackar för koden, Marcus E!

Medlem sedan sep. 20011 914 inlägg
#5

Lite lättare variant.

string date = "Wed, 22 Sep 2004 11:00:00 +0100".Remove(25,6);
DateTime dt = DateTime.Parse(date);
Response.Write(dt.ToString("d"));
Medlem sedan maj 20021 466 inlägg
#6

Dino: Tar du bort tidszonen får du fel tid. Min kod är så lång just därför att den ska garantera att tiden blir rätt oavsett tidszon.

Medlem sedan apr. 20012 266 inlägg
#7

Kan även använda DateTime.ParseExact

.NET Framework Class Library skrev:

public static DateTime ParseExact(
string s,
string format,
IFormatProvider provider
);

I format kan man alltså själv bestämma hur datumet skall "parsas". Ex "ddd, dd mmm yyyy..."

Medlem sedan maj 20021 466 inlägg
#8

renholm skrev:

Kan även använda DateTime.ParseExact

ParseExakt är inte riktigt kompatibel, men om du anpassar tidszonen och den eventuella veckodagen kanske det kan fungera.

287 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
144 ms — deklarationer (db)
0 ms — hämta statistik (cache)
141 ms — hämta tråd, inlägg och bilagor (db)
142 ms — ändringar (db)