【问题标题】:Change system time, time zone and auto checkbox in time and date settings programmatically以编程方式更改时间和日期设置中的系统时间、时区和自动复选框
【发布时间】:2015-06-19 10:30:23
【问题描述】:

我试图弄清楚如何以编程方式编辑时间和“自动设置日期和时间”复选框。我花了一段时间,找不到解决方案。

我尝试查看 NSUserDefault 键,但没有看到它们。

NSLog(@"%@", [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]);

帮助表示赞赏。这是 OSX(不是 iphone)。

【问题讨论】:

  • 您将三个不同的问题合二为一。我这么说的原因是因为没有直接的方法可以完成所有事情。此外,您询问了更改您已经知道如何操作的时区。我说将您的问题编辑为简单明了。

标签: objective-c cocoa nsdate nsuserdefaults nstimezone


【解决方案1】:

这不是一个完整的答案。我只是在下面的代码只会改变系统时间。注意:更改系统时间需要root权限。按原样通过 Xcode IDE 运行代码将失败。使用sudo 命令从终端运行有效。

//
//  main.m
//  TimeChange
//
//  Created by ... on 4/13/15.
//  Copyright (c) 2015 .... All rights reserved.
//

#import <Foundation/Foundation.h>
#import <sys/time.h>
#include <errno.h>

extern int errno;

void NSLogTime(const struct tm *restrict temp, suseconds_t microseconds)
{
    char tmbuf[64], buf[64];
    strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", temp);
    snprintf(buf, sizeof buf, "%s.%06d\n", tmbuf, microseconds);
    NSLog(@"   %@", [[NSString alloc] initWithUTF8String:buf]);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Built from samples based on the URL listed below
        // http://stackoverflow.com/questions/2408976/struct-timeval-to-printable-format
        // http://www.linuxquestions.org/questions/programming-9/c-code-to-change-date-time-on-linux-707384/

        // Do whatever you need to set the following variable
        // In this example I am hard-coding it
        int month = 2;
        int day = 27;
        int year = 2002;

        NSLog(@"Getting current date/time...");
        struct timeval currentTime;
        int success = gettimeofday(&currentTime, 0); // should check for success
        struct tm *localTime = localtime(&currentTime.tv_sec);

        NSLogTime(localTime, currentTime.tv_usec);

        if (localTime)
        {
            NSLog(@"...create new date/time structure...");
            localTime->tm_mon  = month - 1;
            localTime->tm_mday = day;
            localTime->tm_year = year - 1900;

            const struct timeval tv = {mktime(localTime), 0};
            success = settimeofday(&tv, 0);

            // check if we are success
            if (success == 0)
            {
                NSLog(@"...time was changed!");

                // get the new time from the system and display it
                struct timeval updatedTime;
                gettimeofday(&updatedTime, 0); // should check for success
                NSLogTime(localtime(&updatedTime.tv_sec), updatedTime.tv_usec);
            }
            else
            {
                // display the error message
                NSLog(@"Error Setting Date: %s", strerror(errno));
            }
        }

    }
    return 0;
}

下面是在终端中运行的代码的屏幕截图。

注意:输出中的一小时时差是因为夏令时 (DST) 在 2002 年 2 月 22 日没有生效。

【讨论】:

    【解决方案2】:

    所以我发现我可以编写一个可以执行 bash 脚本命令的 applescript。然后我用 NSApplescript 调用了这个脚本。 很酷的是苹果脚本有一个优雅的密码对话框,它只需要处理一次即可。这比让终端出现要好得多。

    缺点是使用 NSApplescript 调用 applescript 的过程。 将 3 个 args 传递给脚本的简单过程需要由大约 50 行过时的 NSAppleEvent 代码来处理,这些代码甚至在 Apple 文档中都不起作用。幸运的是,我找到了一篇帖子,其中有人知道缺席的 Carbon 框架中缺少的常量。

    代码:

    // Caller responsible for well formed ip address.
    +(BOOL)setDateAndTimePreferences:(NSString*)ipAddress setAutoNetworkTime:(BOOL)yNo withTimezone:(NSString*)timezone{
    
        // Load the script from a resource by fetching its URL from within our bundle
        // Note: if the script if stored in a nother file location, NSBundle may not be
        // necessary. Make sure the path to the script is correct.
        NSString* path = [[NSBundle mainBundle] pathForResource:@"date_time_pref" ofType:@"scpt"];
        if (path != nil){
    
            NSURL* url = [NSURL fileURLWithPath:path];
            if (url != nil)
            {
                NSDictionary* errors = [NSDictionary dictionary];
                NSAppleScript* appleScript =
                [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors];
                if (appleScript != nil)
                {
    
                    // Get the value of the setAutoNetwork checkbox.
                    NSString *chkBox = (yNo == YES)? @"on": @"off";
    
                    // Create the arg parameters
                    NSAppleEventDescriptor* firstParameter =
                    [NSAppleEventDescriptor descriptorWithString:ipAddress];
    
                    NSAppleEventDescriptor* secondParameter =
                    [NSAppleEventDescriptor descriptorWithString:chkBox];
    
                    NSAppleEventDescriptor* thirdParameter =
                    [NSAppleEventDescriptor descriptorWithString:timezone];
    
                    // Create and populate the list of parameters.
                    NSAppleEventDescriptor* parameters = [NSAppleEventDescriptor listDescriptor];
                    [parameters insertDescriptor:firstParameter atIndex:1];
                    [parameters insertDescriptor:secondParameter atIndex:2];
                    [parameters insertDescriptor:thirdParameter atIndex:3];
    
                    // Create the AppleEvent target
                    ProcessSerialNumber psn = {0, kCurrentProcess};
                    NSAppleEventDescriptor* target = [NSAppleEventDescriptor
                                                  descriptorWithDescriptorType:typeProcessSerialNumber
                                                  bytes:&psn length:sizeof(ProcessSerialNumber)];
    
                    //  We need these constants from the Carbon OpenScripting
                    // framework, but we don't actually need Carbon.framework.
                    #define kASAppleScriptSuite 'ascr'
                    #define kASSubroutineEvent  'psbr'
                    #define keyASSubroutineName 'snam'
    
                    // Create an NSAppleEventDescriptor with the script's method name to call,
                    // this is used for the script statement: "on   set_preferences(arg1,arg2arg3)"
                // Note that the routine name must be in lower case.
                NSAppleEventDescriptor* handler =
                [NSAppleEventDescriptor descriptorWithString:
                 [@"set_preferences" lowercaseString]];
    
                // Create the event for an AppleScript subroutine,
                // set the method name and the list of parameters
                NSAppleEventDescriptor* event =
                [NSAppleEventDescriptor  appleEventWithEventClass:kASAppleScriptSuite
                                                         eventID:kASSubroutineEvent
                                                targetDescriptor:target
                                                        returnID:kAutoGenerateReturnID
                                                   transactionID:kAnyTransactionID];
                [event setParamDescriptor:handler forKeyword:keyASSubroutineName];
                [event setParamDescriptor:parameters forKeyword:keyDirectObject];
    
                    // call the event in AppleScript
                    if (![appleScript executeAppleEvent:event error:&errors])
                    {
                        // report any errors from 'errors'
                        NSLog(@"Errors %@",[errors description]);
                    }
    
                    [appleScript release];
                }
    
                else{
                    // report any errors from 'errors'
                    NSLog(@"Error: applescript is nil");
                }
    
            }else{
    
                NSLog(@"Could not locate the time_date_preferences script");
                return NO;
            }
    
        }else{
    
            NSLog(@"Could not locate the time_date_preferences script");
            return NO;
        }
    
    
    
        return YES;
    
    }
    

    脚本:

    on set_preferences(ipaddress, chkbox, timezone)
    
        global timezonelist
    
        do shell script "/usr/sbin/systemsetup -setusingnetworktime " & chkbox password "passwordhere" with administrator privileges
        do shell script "/usr/sbin/systemsetup -setnetworktimeserver " & ipaddress with administrator privileges
        set timezonelist to (do shell script "/usr/sbin/systemsetup -listtimezones" with administrator privileges)
    
        if timezonelist contains timezone then
            do shell script "/usr/sbin/systemsetup -settimezone " & timezone with    administrator privileges
    
        else
    
            display notification "Please open Date and Time Preferences and set your time zone manually." with title ("Invalid Time Zone")
           delay 1
        end if
    
    end set_preferences
    

    【讨论】:

      猜你喜欢
      • 2016-04-20
      • 2015-12-03
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      相关资源
      最近更新 更多