[English Version]

MFP语言和可编程科学计算器

MFP语言简介

MFP函数

部署用户自定义函数

在您的应用中调用MFP

创建安卓安装包

小游戏的开发

绘制图形

使用MFP进行数学分析

使用MFP处理文件

数,字符串和数组

日期时间和系统相关

可编程科学计算器介绍

MFP编程语言如何使用时间、日期以及系统函数:

对日期和时间的读写是任何编程语言不可缺少的部分,此外,MFP编程语言还提供了一些系统函数以方便用户直接使用操作系统的一些功能。

第1节  日期和时间的函数

MFP编程语言所提供的日期和时间的函数参见下表:

函数名

函数帮助信息

get_day_of_month

get_day_of_month(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_day_of_week

get_day_of_week(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_day_of_year

get_day_of_year(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_hour

get_hour(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_millisecond

get_millisecond(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_minute

get_minute(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_month

get_month(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_second

get_second(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

get_time_stamp

get_time_stamp(1...) :

get_time_stamp(string_or_year, ...)返回由其参数所决定的时标。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。这个函数有两种工作模式。第一种模式是get_time_stamp(string_time_stamp)。这种模式仅仅接受一个字符串参数,该参数必须基于yyyy-mm-dd hh:mm:ss[.f...]的格式。其中,秒的分数部分可以忽略。第二种模式是get_time_stamp(year, month, day, hour, minute, second, millisecond)。这些参数中,除了第一个参数year(年),所有的其他参数都可以省略。如果省略,month(月)和day(日)的缺省值是1,hour(小时),minute(分钟),second(秒)和millisecond(毫秒)的缺省值是0。比如get_time_stamp("1981-05-30 17:05:06")返回1981年5月30日17点5分6秒0毫秒的时标,用户也可以调用get_time_stamp(1981, 5, 30, 17, 5, 6, 0)获得同样的结果。

get_year

get_year(1) :

get_year(timestamp),get_month(timestamp),get_day_of_year(timestamp),get_day_of_month(timestamp),get_day_of_week(timestamp),get_hour(timestamp),get_minute(timestamp),get_second(timestamp)和get_millisecond(timestamp) 分别返回时标timestamp所对应的年,月,本年中的第几天,本月中的第几天,本星期中的第几天(礼拜天是第0天,礼拜一是第一天,...),小时,分钟,秒钟和毫秒。时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差。例如,get_day_of_week(get_time_stamp(2014, 12, 21))返回0,表示2014年12月21日是礼拜天。

now

now(0) :

now()返回当前时刻和1970年1月1日午夜(UTC)的毫秒数时间差。

上述函数的用法均比较简单,其中,get_day_of_month,get_day_of_week,get_day_of_year,get_hour,get_millisecond,get_minute,get_month,get_second和get_year均为将一个时标(时标是时标所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差)转换为人能够看得懂的时间,而get_time_stamp是将一个供人读取的时间转换为时标,now函数则是返回当前时间所对应的时标。

以下是上述函数的一个例子。本示例的代码可以在本手册自带的示例代码所在目录中的time date and sys libs子目录中的examples.mfps文件中找到。

Help

@language:

  test time and date functions

@end

@language:simplified_chinese

  测试日期和时间相关函数

@end

endh

function testTimeDate()

  variable var1

  print("\n\nget_time_stamp(\"1970-01-01 00:00:00.0\") = " _

    + get_time_stamp("1970-01-01 00:00:00.0"))

 

  // test to convert an invalid time string to a time stamp.

  // Result depends on OS

  //测试将一个不合法的时间表达式转换为时标,

  //在不同的操作系统上会有不同的结果。

  try

    print("\n\nget_time_stamp(\"1980-12-71 00:00:00.0\") = ")

    print(get_time_stamp("1980-12-71 00:00:00.0"))

  catch  (var1 = info) == info

    print("throws an exception")

  endtry

 

  // test now function

  //测试now函数

  printf("\n\nnow year = %d, month = %d, day of year = %d, " _

    + "day of month = %d, day of week = %d, hour = %d, " _

    + "minute = %d, second = %d, ms = %d", _

    get_year(now()), get_month(now()), get_day_of_year(now()), _

    get_day_of_month(now()), get_day_of_week(now()), _

    get_hour(now()), get_minute(now()), get_second(now()), _

    get_millisecond(now()))

 

  // test time stamp conversions

  //测试时标转换函数

  print("\n\nget_millisecond(get_time_stamp(2015, 3, 8, 21, 22, 9, 7)) = " _

    + get_millisecond(get_time_stamp(2015, 3, 8, 21, 22, 9, 7)))

  print("\n\nget_second(get_time_stamp(2015, 3, 8, 21, 22, 19, 700)) = " _

    + get_second(get_time_stamp(2015, 3, 8, 21, 22, 19, 700)))

  print("\n\nget_month(get_time_stamp(2000, 2,29, 16, 58, 9, 700)) = " _

    + get_month(get_time_stamp(2000, 2,29, 16, 58, 9, 700)))

  print("\n\nget_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = " _

    + get_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)))

  print("\n\nget_day_of_week(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = " _

    + get_day_of_week(get_time_stamp(2014, 12,15, 16, 58, 9, 700)))

  print("\n\nget_day_of_month(get_time_stamp(2001, 2,29, 16, 58, 9, 700)) = " _

    + get_day_of_month(get_time_stamp(2001, 2,29, 16, 58, 9, 700)))

  print("\n\nget_day_of_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = " _

    + get_day_of_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)))

 

  // test conversion of an invalid time. Result depends on OS

  //测试转化一个非法的时间,在不同的操作系统上会有不同的结果。

  try

    print("\n\nget_hour(get_time_stamp(2014, 12,15, 116, 58, 9, 700)) = " _

      + get_hour(get_time_stamp(2014, 12,15, 116, 58, 9, 700)))

  catch  (var1 = info) == info

    print("\n\nget_hour(get_time_stamp(2014, 12,15, 116, 58, 9, 700)) " _

      + "throws an exception")

  endtry

endf

上述代码的运行结果如下:

get_time_stamp("1970-01-01 00:00:00.0") = -36000000

get_time_stamp("1980-12-71 00:00:00.0") = throws an exception

now year = 2015, month = 8, day of year = 228, day of month = 16, day of week = 0, hour = 22, minute = 13, second = 9, ms = 363

get_millisecond(get_time_stamp(2015, 3, 8, 21, 22, 9, 7)) = 7

get_second(get_time_stamp(2015, 3, 8, 21, 22, 19, 700)) = 19

get_month(get_time_stamp(2000, 2,29, 16, 58, 9, 700)) = 2

get_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = 2014

get_day_of_week(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = 1

get_day_of_month(get_time_stamp(2001, 2,29, 16, 58, 9, 700)) = 1

get_day_of_year(get_time_stamp(2014, 12,15, 16, 58, 9, 700)) = 349

get_hour(get_time_stamp(2014, 12,15, 116, 58, 9, 700)) = 20

这里需要注意一点,如果get_time_stamp接受的参数不是一个合法的时间表达式,比如"1980-12-71 00:00:00.0"(日期不合法),那么get_time_stamp的行为是不确定的,在有的操作系统上会出错,在有的操做系统上却能够返回一个时标。所以,用户在调用这些函数时,要尽可能地保证参数的正确性。

第2节  系统相关函数

MFP编程语言提供的和操作系统调用相关的函数包括两个,一个是sleep,另一个是system。

Sleep函数用于暂停当前正在运行中的函数一段固定的时间然后再继续。Sleep函数的调用方法为sleep(x),这里x是一个正实数,表示程序暂停的毫秒数。此函数不返回任何值。

System函数则用于运行一个系统指令并且返回该系统指令的返回值。它有两种用法,第一种用法,也是1.6.6版和更老的版本的唯一的用法,参数是一个字符串,该字符串就是所要执行的系统指令,注意系统指令必须是一个可执行的文件以及它的命令参数。由于这个原因,在Windows平台上运行基于JAVA的可编程科学计算器,诸如system("dir")是无法正确执行的,因为dir并非是一个单独的可执行文件,而是cmd.exe的一个内部功能。要执行dir指令,用户需要运行system("cmd /c dir");类似地,如果在Linux平台上运行基于JAVA的可编程科学计算器,要执行ls指令,用户需要运行system("sh -c ls")。

system函数的第一种用法可以在JAVA平台上运行,但是在安卓平台上,如果执行比如system("sh -c ls"),就会出错,从1.6.7版开始,system函数提供另外一种用法,它还是接受一个参数,但这个参数必须是一个字符串数组,数组的每一个元素是系统指令的一部分。比如,要执行"sh -c ls",可以调用system(["sh", "-c", "ls"])。而要执行将文件file1改名为file2,需要调用system(["sh", "-c", "mv file1 file2"]),原因是"mv file1 file2"是sh的一个内部指令,它不能被人为地分割为几个部分。

还要注意,在现阶段,这个函数只能将系统指令的输出打印出来,还无法接受在运行中用户对于该系统指令的输入。此外,如果该系统指令不存在,则会抛出异常。

需要指出的是,system函数在基于JAVA的可编程科学计算器上工作是没有问题的,但是在安卓系统上,功能受到很多限制,原因在于,安卓系统并不保证提供完整的sh(shell)调用,所以,有些命令比如system(["sh", "-c", "echo hello"])可能在一些手机上可以执行,在另外一些手机上会运行出错。要想在安卓上执行文件复制移动删除以及目录的转换等操作,建议用户调用第6章第5节中提供的对文件整体操作的函数而最好不要去运行比如system(["sh", "-c", "cp file1 file2"])。

那么,是不是system函数在安卓上就没有什么很大的作用了呢?也不是,system函数可以调用安卓内部的应用管理器以打开某个应用,前提条件是用户知道该应用的包id(package id)和主界面(main activity)的名字,具体的用法为:

system("am start –n 包ID/启动主界面的名字")

比如,如果用户的手机上安装有智慧拍照计算器(可编程科学计算器的姊妹产品),启动智慧拍照计算器的命令为:

system("am start –n com.cyzapps.SmartMath/com.cyzapps.SmartMath.ActivitySmartCalc")

这里com.cyzapps.SmartMath是智慧拍照计算器的包ID,com.cyzapps.SmartMath.ActivitySmartCalc是启动主界面的名字。

可编程科学计算器具有生成APK应用的功能,这些应用的包ID是由用户指定的,但是启动主界面的名字是固定的(但要注意该名字可能会在以后的版本中更改,但无论如何如果用户的APP已经生成,启动主界面的名字就不会变了),总是com.cyzapps.AnMFPApp.ActivityAnMFPMain。所以,用户可以在MFP程序中启动自己的MFP应用。

安卓内部的应用管理器也具有终止某个进程的功能,但是,这需要具有相应的权限。为了安全起见,可编程科学计算器没有添加相应的权限,所以,System函数不能用于终止某个应用。

以下是上述函数的一个例子。本示例的代码可以在本手册自带的示例代码所在目录中的time date and sys libs子目录中的examples.mfps文件中找到。

Help

@language:

  test sleep and system functions

@end

@language:simplified_chinese

  测试sleep和system函数

@end

endh

function testSleepSys()

  print("Now sleep 3 seconds\n")

  sleep(3000)

  print("Now wake up!\n")

  // If you have installed Smart Photographic Calculator, this will work

  //如果您已经安装了智慧拍照计算器软件,下述语句将启动它

  pause("Now try to start Smart Photographic Calculator. Press Enter to continue")

  system("am start –n com.cyzapps.SmartMath/com.cyzapps.SmartMath.ActivitySmartCalc")

endf

运行上述代码,用户先会看到一条打印输出为Now sleep 3 seconds,然后程序停顿3秒,又打印输出Now wake up!。最后,程序尝试启动智慧拍照计算器,如果不成功,则打印出错误信息。

小结

日期时间函数是进行编程的不可缺少的部分。在所有的操作系统中,对时间的描述是基于时标,也就是所表示的时刻和1970年1月1日午夜(UTC)的毫秒数时间差,MFP编程语言提供了一组函数用于时标和人可读的时间信息之间的相互转换,大大方便了程序和用户在时间上进行交互。

MFP编程语言还提供了一些系统相关的函数,比如sleep函数用于暂停正在运行的程序,system函数用于调用一个系统指令。需要注意的是,在安卓系统上,不推荐直接调用操作系统的shell指令,原因在于由于对shell指令的实现不同,在不同的安卓上,同样的system命令可能得到不同的结果。System函数在安卓系统上更多地用来启动某一个应用,如果用户知道该应用的主界面的名称的话。