[Mono-list] Troubling passing DateTime via embedded API

jonathan at mugginsoft.com jonathan at mugginsoft.com
Fri Jul 26 12:09:32 UTC 2013


On 25 Jul 2013, at 18:40, Aaron Oneal <aaron.oneal at spicypixel.com> wrote:

> Can you share a code snippet? Are you using mono_object_to_string to retrieve the string value for display?
> 
Perhaps the code below will help illustrate the point.

In C the tick count looks okay by my reckoning but the string representation is bad:

Obj-C:
// NSLog(@"NSDate date = %@ Mono DateTime = %@ ticks = %lld", dateNow, dateString, ticks); says
NSDate date = 2013-07-26 09:19:30 +0000 Mono DateTime = 01/01/0001 00:00:01 ticks = 635104271706805504

When I send the Mono DateTime to a C# property incoming argument gets logged as:
C#:
DateMethod arguments : 01/01/0001 00:00:01 ticks = 12436392

This is on Mono 3.0.10. I will check out 3.2.0

Obj-C:
- (void)testDateRepresentation
{
    NSDate *dateNow = [NSDate date];
    MonoObject *monoDateTime = [dateNow monoDateTime];
    NSDate *dateFromMonoObject = [[NSDate alloc} initWithMonoDateTime:monoDateTime];
    
    // validate the NSDate representation
    NSAssert(fabs([dateFromMonoObject timeIntervalSinceDate:dateNow]) < 0.1, @"bad date");  // sanity check
    
    // validate the Mono representatiom
    int64_t ticks = DB_UNBOX_INT64(DBMonoObjectGetProperty(monoDateTime, "Ticks"));
    MonoString *monoString = mono_object_to_string(monoDateTime, NULL);
    NSString *dateString = [NSString stringWithMonoString:monoString];
    NSLog(@"NSDate date = %@ Mono DateTime = %@ ticks = %lld", dateNow, dateString, ticks);	// see output above ^
}

// NSDate 

- (id)initWithMonoDateTime:(MonoObject *)monoDateTime {
	MonoObject *boxedTicks = DBMonoObjectGetProperty(monoDateTime, "Ticks");	
	int64_t ticks = DB_UNBOX_INT64(boxedTicks);
	NSTimeInterval interval = (NSTimeInterval)(ticks - EPOCH_START_DIFFERENCE) / NET_TICKS_PER_SECOND;
	self = [self initWithTimeIntervalSinceReferenceDate:interval];

	return(self);
}

// Mono property

MonoObject *DBMonoObjectGetProperty(MonoObject *monoObject, const char *propertyName) {
	MonoObject *monoException = NULL;
	MonoClass *klass = mono_object_get_class(monoObject);
	MonoMethod *monoMethod = GetPropertyGetMethod(klass, propertyName);
	
	MonoObject *retval = NULL;
	if(monoMethod != NULL) {
		void *invokeObj = mono_class_is_valuetype(klass) ? mono_object_unbox(monoObject) : monoObject;
		retval = mono_runtime_invoke(monoMethod, invokeObj, NULL, &monoException);
	}
	
	if(monoException != NULL) @throw(NSExceptionFromMonoException(monoException));
	
	return(retval);
}

C#
        // date methods
        public DateTime DateMethod(DateTime d1)
        {
            DateTime now = DateTime.UtcNow;

            Console.WriteLine ("DateMethod arguments : {0} ticks = {1}", d1, d1.Ticks);
            Console.WriteLine ("DateTime Now : {0} ticks = {1}", now, now.Ticks);
            return d1;
        }

Jonathan


More information about the Mono-list mailing list