// Copyright (C) 2004 MySQL AB // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as published by // the Free Software Foundation // // There are special exceptions to the terms and conditions of the GPL // as it is applied to this software. View the full text of the // exception in file EXCEPTIONS in the directory of this software // distribution. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; using System.Data; using MySql.Data.MySqlClient; namespace MySql.Data.Types { /// /// Summary description for MySqlDateTime. /// public class MySqlDateTime : MySqlValue, IConvertible { private DateTime mValue; private bool isZero; internal MySqlDateTime() { dbType = DbType.DateTime; mySqlDbType = MySqlDbType.Datetime; } internal MySqlDateTime(MySqlDbType type) : this() { if (type == MySqlDbType.Date) dbType = DbType.Date; else dbType = DbType.DateTime; mySqlDbType = type; } internal MySqlDateTime(DateTime val, MySqlDbType type) : this(type) { mValue = val; } /// Indicates if this value is zero public bool IsZero { get { return isZero; } } internal override void SerializeBinary(PacketWriter writer) { Packet p = new Packet(false); if (mySqlDbType == MySqlDbType.Timestamp) writer.WriteByte( 11 ); else writer.WriteByte( 7 ); writer.WriteInteger( mValue.Year, 2 ); writer.WriteByte( (byte)mValue.Month ); writer.WriteByte( (byte)mValue.Day ); if (mySqlDbType == MySqlDbType.Date) { writer.WriteByte( 0 ); writer.WriteByte( 0 ); writer.WriteByte( 0 ); } else { writer.WriteByte( (byte)mValue.Hour ); writer.WriteByte( (byte)mValue.Minute ); writer.WriteByte( (byte)mValue.Second ); } if (mySqlDbType == MySqlDbType.Timestamp) writer.WriteInteger( mValue.Millisecond, 4 ); } /// Returns this value as byte[] public override byte[] ToBytes() { Packet p = new Packet(false); byte len = 11; if (mySqlDbType == MySqlDbType.Date) len = 7; p.WriteByte( len ); p.WriteInteger( mValue.Year, 2 ); p.WriteByte( (byte)mValue.Month ); p.WriteByte( (byte)mValue.Day ); if (mySqlDbType == MySqlDbType.Date) { p.WriteByte( 0 ); p.WriteByte( 0 ); p.WriteByte( 0 ); } else { p.WriteByte( (byte)mValue.Hour ); p.WriteByte( (byte)mValue.Minute ); p.WriteByte( (byte)mValue.Second ); } if (mySqlDbType == MySqlDbType.Timestamp) p.WriteInteger( mValue.Millisecond, 4 ); byte[] buff = new byte[len+1]; Array.Copy( p.GetBuffer(), 0, buff, 0, len+1 ); return buff; } internal override DbType DbType { get { switch (mySqlDbType) { case MySqlDbType.Date: case MySqlDbType.Newdate: return DbType.Date; } return DbType.DateTime; } } internal override string GetMySqlTypeName() { switch (mySqlDbType) { case MySqlDbType.Date: return "DATE"; case MySqlDbType.Newdate: return "NEWDATE"; case MySqlDbType.Timestamp: return "TIMESTAMP"; } return "DATETIME"; } internal override object ValueAsObject { get { return mValue; } set { mValue = Convert.ToDateTime(value); } } /// Returns this value as a DateTime public DateTime Value { get { return mValue; } set { mValue = value; } } /// Parses a string into this value /// public override void Parse(string s) { mValue = DateTime.Parse(s); } internal void ParseMySql( string s, bool is41 ) { isZero = false; switch (mySqlDbType) { case MySqlDbType.Date: if (s == "0000-00-00") isZero = true; else mValue = DateTime.ParseExact( s, "yyyy-MM-dd", System.Globalization.DateTimeFormatInfo.InvariantInfo ); break; case MySqlDbType.Datetime: if (s == "0000-00-00 00:00:00") isZero = true; else mValue = DateTime.ParseExact( s, "yyyy-MM-dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo ); break; case MySqlDbType.Timestamp: // MySql 4.1.0 and later use DateTime format for timestamp if (is41) { if (s == "0000-00-00 00:00:00") isZero = true; else mValue = DateTime.ParseExact( s, "yyyy-MM-dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo ); return; } string pattern; switch (s.Length) { case 2: pattern = "yy"; break; case 4: pattern = "yyMM"; break; case 6: pattern = "yyMMdd"; break; case 8: pattern = "yyyyMMdd"; break; case 10: pattern = "yyMMddHHmm"; break; case 12: pattern = "yyMMddHHmmss"; break; case 14: default: pattern = "yyyyMMddHHmmss"; break; } if (s.Replace("0","").Length == 0) isZero = true; else mValue = DateTime.ParseExact( s, pattern, System.Globalization.DateTimeFormatInfo.InvariantInfo ); break; } } internal override Type SystemType { get { return typeof(DateTime); } } internal override long SetBinaryData(Packet packet) { long bufLength = 0; bufLength = packet.ReadByte(); if (bufLength == 0) IsNull = true; else if (bufLength == 4) mValue = new DateTime( packet.ReadInteger(2), packet.ReadByte(), packet.ReadByte() ); else if (bufLength == 7) mValue = new DateTime( packet.ReadInteger(2), packet.ReadByte(), packet.ReadByte(), packet.ReadByte(), packet.ReadByte(), packet.ReadByte() ); else if (bufLength == 11) mValue = new DateTime( packet.ReadInteger(2), packet.ReadByte(), packet.ReadByte(), packet.ReadByte(), packet.ReadByte(), packet.ReadByte(), packet.ReadInteger(4) / 1000000 ); return bufLength; } /// Returns a MySQL specific string representation of this value public override string ToString() { if (mySqlDbType == MySqlDbType.Date) return IsZero ? "0000-00-00" : Value.ToString("yyyy-MM-dd"); return IsZero ? "0000-00-00 00:00:00" : Value.ToString( "yyyy-MM-dd HH:mm:ss" ); } internal string ToMySqlString(bool is41) { switch (mySqlDbType) { case MySqlDbType.Date: return mValue.ToString("yyyy-MM-dd"); case MySqlDbType.Datetime: return mValue.ToString("yyyy-MM-dd HH:mm:ss"); case MySqlDbType.Timestamp: if (is41) return mValue.ToString("yyyy-MM-dd HH:mm:ss"); else return mValue.ToString("yyyyMMddHHmmss"); } return mValue.ToString(); } #region IConvertible Members ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convert.ToUInt64( mValue ); } sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convert.ToSByte( mValue ); } double IConvertible.ToDouble(IFormatProvider provider) { return Convert.ToDouble( mValue ); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return mValue; } float IConvertible.ToSingle(IFormatProvider provider) { return Convert.ToSingle( mValue ); } bool IConvertible.ToBoolean(IFormatProvider provider) { return Convert.ToBoolean( mValue ); } int IConvertible.ToInt32(IFormatProvider provider) { return Convert.ToInt32( mValue ); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convert.ToUInt16( mValue ); } short IConvertible.ToInt16(IFormatProvider provider) { return Convert.ToInt16( mValue ); } string IConvertible.ToString(IFormatProvider provider) { return ToString(); } byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte( mValue ); } char IConvertible.ToChar(IFormatProvider provider) { return Convert.ToChar( mValue ); } long IConvertible.ToInt64(IFormatProvider provider) { return Convert.ToInt64( mValue ); } TypeCode IConvertible.GetTypeCode() { return TypeCode.Object; } decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convert.ToDecimal( mValue ); } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return null; } uint IConvertible.ToUInt32(IFormatProvider provider) { return Convert.ToUInt32( mValue ); } #endregion } }